溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Vue中jsx不完全應(yīng)用的示例分析

發(fā)布時間:2021-09-01 14:07:33 來源:億速云 閱讀:137 作者:小新 欄目:web開發(fā)

這篇文章主要介紹Vue中jsx不完全應(yīng)用的示例分析,文中介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們一定要看完!

在使用Vue開發(fā)項(xiàng)目時絕大多數(shù)情況下都是使用模板來寫HTML,但是有些時候頁面復(fù)雜又存在各種條件判斷來顯示/隱藏和拼湊頁面內(nèi)容,或者頁面中很多部分存在部分DOM結(jié)構(gòu)一樣的時候就略顯捉襟見肘,會寫大量重復(fù)的代碼,會出現(xiàn)單個.vue文件過長的情況,這個時候我們就需要更多的代碼控制,這時候可以使用渲染函數(shù)。

渲染函數(shù)想必平時幾乎沒有人去寫,因?yàn)閷懫饋砗芡纯啵ū救艘矝]有寫過)。更多的是在Vue中使用JSX語法。寫法上和在React中差不多,但是功能上還是沒有React中那么完善。

在寫JSX的過程中不得考慮一個樣式的問題,雖然可以直接在.vue文件中不寫<tempate>部分,只寫<script>和<style>部分,而不用擔(dān)心樣式作用域問題。但是更多的時候還是推薦直接使用.js的方式來寫組件,這個時候就涉及到樣式作用域的問題了。

在React的生態(tài)中,有很多CSS-IN-JS的解決方案,比如styled-jsx、emotion、styled-components等,目前最活躍和用戶量最多的是styled-components,目前已經(jīng)擁有良好的生態(tài)圈子。如果需要在樣式中作一些像Sass/Less中的顏色計算,可以使用polished來實(shí)現(xiàn),當(dāng)然不止這么簡單的功能。但是在Vue中可使用的方案就太少了,因?yàn)閂ue使用模板來寫HTML本身是開箱即用的樣式scoped,在使用JSX寫組件的時候就面臨著樣式問題,一種方案是在組件包裹<div>中取一個特殊的名字,然后樣式都嵌套寫在這個class下面,但是難免會遇到命名沖突的情況,而且每次還得變著花樣取名稱。此外,就是引入CSS-IN-JS在Vue對應(yīng)的實(shí)現(xiàn),但目前來看Styled-components官方提供了一個Vue版本的叫vue-styled-components和emotion的vue-emotion,但是用的人實(shí)在太少。像styled-components進(jìn)行了重大更新和變化,但是Vue版本的還是最初的版本,而且有時候還出現(xiàn)樣式不生效的情況。

接下來進(jìn)入正題,從簡單語法到經(jīng)驗(yàn)分享(大牛請繞行)

基本用法

首先需要約定一下,使用JSX組件命名采用首字母大寫的駝峰命名方式,樣式可以少的可以直接基于vue-styled-components寫在同一個文件中,復(fù)雜的建議放在單獨(dú)的_Styles.js_文件中,當(dāng)然也可以不采用CSS-IN-JS的方式,使用Less/Sass來寫,然后在文件中import進(jìn)來。

下面是一個通用的骨架:

import styled from 'vue-styled-components'

const Container = styled.div`
 heigth: 100%;
`

const Dashboard = {
 name: 'Dashboard',
 
 render() {
 return (
  <Container>內(nèi)容</Container>
 )
 }
}

export default Dashboard

插值

在JSX中使用單個括號來綁定文本插值

<span>Message: {this.messsage}</span>
<!-- 類似于v-html -->
<div domPropsInnerHTML={this.dangerHtml}/>
<!-- v-model -->
<el-input v-model={this.vm.name} />

在jsx中不需要把v-model分成事件綁定和賦值二部分分開來寫,因?yàn)橛邢鄳?yīng)的babel插件來專門處理。

樣式

在JSX中可以直接使用class="xx"來指定樣式類,內(nèi)聯(lián)樣式可以直接寫成

<div class="btn btn-default" >Button</div>

<!-- 動態(tài)指定 -->
<div class={`btn btn-${this.isDefault ? 'default' : ''}`}></div>
<div class={{'btn-default': this.isDefault, 'btn-primary': this.isPrimary}}></div>
<div style={{color: 'red', fontSize: '14px'}}></div>

遍歷

在JSX中沒有v-for和v-if等指令的存在,這些全部需要采用Js的方式來實(shí)現(xiàn)

{/* 類似于v-if */}
{this.withTitle && <Title />}

{/* 類似于v-if 加 v-else */}
{this.isSubTitle ? <SubTitle /> : <Title />}

{/* 類似于v-for */}
{this.options.map(option => {
 <div>{option.title}</div>
})}

事件綁定

事件綁定需要在事件名稱前端加上on前綴,原生事件添加nativeOn

<!-- 對應(yīng)@click -->
<el-buton onClick={this.handleClick}>Click me</el-buton>
<!-- 對應(yīng)@click.native -->
<el-button nativeOnClick={this.handleClick}>Native click</el-button>
<!-- 傳遞參數(shù) -->
<el-button onClick={e => this.handleClick(this.id)}>Click and pass data</el-button>

注意:如果需要給事件處理函數(shù)傳參數(shù),需要使用箭頭函數(shù)來實(shí)現(xiàn)。如果不使用箭頭函數(shù)那么接收的將會是事件的對象event屬性。

高級部分

在Vue中基于jsx也可以把組件拆分成一個個小的函數(shù)式組件,但是有一個限制是必需有一個外層的包裹元素,不能直接寫類似:

const Demo = () => (
 <li>One</li>
 <li>Two</li>
)

必需寫成:

const Demo = () => (
 <div>
  <li>One</li>
 <li>Two</li>
 </div>
)

而在React中可以使用空標(biāo)簽<></>和<react.Fragment></react.Fragment>來實(shí)現(xiàn)包裹元素,這里的空標(biāo)簽其實(shí)只是react.Fragment的一個語法糖。同時在React 16中直接支持返回數(shù)組的形式:

const Demo = () => [
 <li>One</li>
 <li>Two</li>
]

那么在Vue中就只能通過遍歷來實(shí)現(xiàn)類似的功能,大體思路就是把數(shù)據(jù)先定義好數(shù)據(jù)然后直接一個map生成,當(dāng)然如果說元素的標(biāo)簽是不同類型的那就需要額外添加標(biāo)識來判斷了。

{
 data() {
 return {
  options: ['one', 'two']
 }
 },
 
 render() {
 const LiItem = () => this.options.map(option => <li>{option}</li>)
           
 return (
  <div>
   <ul>
    <LiItem />
   </ul>
   </div>
 )
 }
}

事件修飾符

在基礎(chǔ)部分簡單介紹了事件的綁定用法,這里主要是補(bǔ)充一下事件修飾符的寫法。

在模板語法中Vue提供了很多事件修飾符來快速處理事件的冒泡、捕獲、事件觸發(fā)頻率、按鍵識別等??梢灾苯硬榭垂俜轿臋n的事件&按鍵修飾符部分,這里把相關(guān)內(nèi)容原樣搬運(yùn)過來:

修飾符前綴
.passive&
.capture!
.once~
.capture.once或.once.capture~!

使用方式如下:

<el-button {...{
 '!click': this.doThisInCapturingMode,
 '!keyup': this.doThisOnce,
 '~!mouseover': this.doThisOnceInCapturingMode
}}>Click Me!</el-button>

下面給出的事件修飾符是需要在事件處理函數(shù)中寫出對應(yīng)的等價操作

修飾符處理函數(shù)中的等價操作
.stopevent.stopPropagation()
.preventevent.preventDefault()
.selfif (event.target !== event.currentTarget) return
按鍵: .enter, .13if (event.keyCode !== 13) return (對于別的按鍵修飾符來說,可將 13 改為另一個按鍵碼)
修飾鍵: .ctrl, .alt, .shift, .metaif (!event.ctrlKey) return (將 ctrlKey 分別修改為 altKey、shiftKey 或者 metaKey)

下面是在事件處理函數(shù)中使用修飾符的例子:

methods: {
 keyup(e) {
 // 對應(yīng)`.self`
 if (e.target !== e.currentTarget) return
 
 // 對應(yīng) `.enter`, `.13`
 if (!e.shiftKey || e.keyCode !== 13) return
 
 // 對應(yīng) `.stop`
 e.stopPropagation()
 
 // 對應(yīng) `.prevent`
 e.preventDefault()
 
 // ...
 }
}

ref和refInFor

在Vue中ref被用來給元素或子組件注冊引用信息。引用信息將會注冊在父組件的 $refs 對象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子組件上,引用就指向組件。

注意:

  • 因?yàn)?ref 本身是作為渲染結(jié)果被創(chuàng)建的,在初始渲染的時候你不能訪問它們 - 它們還不存在

  • $refs不是響應(yīng)式的,因此你不應(yīng)該試圖用它在模板中做數(shù)據(jù)綁定。

當(dāng) v-for 用于元素或組件的時候,引用信息將是包含 DOM 節(jié)點(diǎn)或組件實(shí)例的數(shù)組。

假如在jsx中想要引用遍歷元素或組件的時候,例如:

const LiArray = () => this.options.map(option => (
 <li ref="li" key={option}>{option}</li>
))

會發(fā)現(xiàn)從this.$refs.li中獲取的并不是期望的數(shù)組值,這個時候就需要使用refInFor屬性,并置為true來達(dá)到在模板中v-for中使用ref的效果:

const LiArray = () => this.options.map(option => (
 <li ref="li" refInFor={true} key={option}>{option}</li>
))

插槽(v-slot)

在jsx中可以使用this.$slots來訪問靜態(tài)插槽的內(nèi)容。

注意:在Vue 2.6.x版本后廢棄了slot和slot-scope,在模板中統(tǒng)一使用新的統(tǒng)一語法v-slot指令。v-slot只能用于Vue組件和template標(biāo)簽。

<div class="page-header__title">
 {this.$slots.title ? this.$slots.title : this.title}
</div>

等價于模板的

<div class="page-header__title">
 <slot name="title">{{ title }}</slot>
</div>

在Vue官方文檔中提到:父級模板里的所有內(nèi)容都是在父級作用域中編譯的;子模板里的所有內(nèi)容都是在子作用域中編譯的。因此像下面的示例是無法正常工作的

<current-user>
 {{ user.firstName }}
</current-user>

在<current-user>組件中可以訪問到user屬性,但是提供的內(nèi)容卻是在父組件渲染的。如果想要達(dá)到期望的效果,這個時候就需要使用作用域插槽了。下面是改寫后的代碼,更多知識點(diǎn)可以直接查看官方文檔的作用域插槽。

<!-- current-user組件定義部分 -->
<span>
 <slot v-bind:user="user">
  {{ user.lastName }}
 </slot>
</span>

<!-- current-user 使用 -->
<current-user>
 <template v-slot:default="slotProps">
  {{ slotProps.user.firstName }}
 </template>
</current-user>

上面的示例其實(shí)就是官方的示例,這里需要說明的是,其實(shí)在Vue中所謂的作用域插槽功能類似于React中的Render Props的概念,只不過在React中我們更多時候不僅提供了屬性,還提供了操作方法。但是在Vue中更多的是提供數(shù)據(jù)供父作用域渲染展示,當(dāng)然我們也可以把方法提供出去,例如:

<template>
 <div>
 <slot v-bind:injectedProps="slotProps">
  {{ user.lastName }}
  </slot>
 </div>
</template>

<script>
 export default {
 data() {
  return {
  user: {
   firstName: 'snow',
   lastName: 'wolf'
  }
  }
 },
 
 computed: {
  slotProps() {
  return {
   user: this.user,
   logFullName: this.logFullName
  }
  }
 },
 
 methods: {
  logFullName() {
  console.log(`${this.firstName} ${this.lastName}`)
  }
 }
 }
</script>

在父組件中使用:

<current-user>
 <template v-slot:default="{ injectedProps }">
  <div>{{ injectedProps.user.firstName }}</div>
  <el-button @click="injectedProps.logFullName">Log Full Name</el-button>
 </template>
</current-user>

在上面的代碼中我們實(shí)際上使用解構(gòu)的方式來取得injectedProps,基于解構(gòu)的特性還可以重命名屬性名,在prop為undefined的時候指定初始值。

<current-user v-slot="{ user = { firstName: 'Guest' } }">
 {{ user.firstName }}
</current-user>

如果組件只有一個默認(rèn)的插槽還可以使用縮寫語法,將v-slot:default="slotProps"寫成v-slot="slotProps",命名插槽寫成v-slot:user="slotProps",如果想要動態(tài)插槽名還可以寫成v-slot:[dynamicSlotName],此外具名插槽同樣也有縮寫語法,例如 v-slot:header可以被重寫為#header

上面介紹了很多插槽相關(guān)的知識點(diǎn)足已說明其在開發(fā)過程中的重要性。說了很多在模板中如何定義和使用作用域插槽,現(xiàn)在進(jìn)入正題如何在jsx中同樣使用呢?

// current-user components
{
 data() {
 return {
  user: {
  firstName: 'snow',
  lastName: 'wolf'
  }
 }
 },
 
 computed: {
 slotProps() {
  return {
  user: this.user,
  logFullName: this.logFullName
  }
 }
 },
 
 methods: {
 logFullName() {
  console.log(`${this.firstName} ${this.lastName}`)
 }
 },
 
 render() {
 return (
  <div>
  {this.$scopedSlots.subTitle({
   injectedProps: this.slotProps
  })}
  </div>
 )
 }
}

然后在父組件中以jsx使用:

<current-user {...{
 scopedSlots: {
 subTitle: ({ injectedProps }) => (
  <div>
   <h4>injectedProps.user</h4>
  <el-button onClick={injectedProps.logFullName}>Log Full Name</el-button>
  </div>
 )
 }
}}></current-user>

指令

這里需要注意的是在jsx中所有Vue內(nèi)置的指令除了v-show以外都不支持,需要使用一些等價方式來實(shí)現(xiàn),比如v-if使用三目運(yùn)算表達(dá)式、v-for使用array.map()等。

對于自定義的指令可以使用v-name={value}的語法來寫,需要注意的是指令的參數(shù)、修飾符此種方式并不支持。以官方文檔指令部分給出的示例v-focus使用為例,介紹二種解決辦法:

1 直接使用對象傳遞所有指令屬性

<input type="text" v-focus={{ value: true }} />

2 使用原始的vnode指令數(shù)據(jù)格式

{
 directives:{
 focus: {
  inserted: function(el) {
  el.focus()
  }
 }
 },
 
 render() {
 const directives = [
  { name: 'focus', value: true }
 ]
  
 return (
  <div>
   <input type="text" {...{ directives }} />
  </div>
 )
 }
}

過濾器

過濾器其實(shí)在開發(fā)過程中用得倒是不多,因?yàn)?strong>更多時候可以通過計算屬性來對數(shù)據(jù)做一些轉(zhuǎn)換和篩選。這里只是簡單提及一下并沒有什么可以深究的知識點(diǎn)。

在模板中的用法如下:

<!-- 在雙花括號中 -->
{{ message | capitalize }}

<!-- 在 `v-bind` 中 -->
<div v-bind:id="rawId | formatId"></div>

在jsx中使用方法為:

<div>{this.$options.filters('formatDate')('2019-07-01')}</div>

注意:由于Vue全局的過濾器只用于模板中,如果需要用于組件的方法中,可以把過濾器方法單獨(dú)抽離出一個公共Js文件,然后引入組件中,然后用于方法中。

一些簡單經(jīng)驗(yàn)分享

并不是說我們在開發(fā)Vue項(xiàng)目的時候一定要使用jsx的方式來寫,但是多掌握一種方式來靈活變通,提高工作效率,擴(kuò)展思路何嘗不值得一試。而且,在有些場景下釋放js的完全編程能力會讓你更加能夠得心應(yīng)手。其實(shí)在使用模板方式的時候我們并沒有完全采用組件的思維方式來做,或者說是做得不徹底,不純粹,拆分的粒度不夠。更多 的時候并沒有考慮到組件怎么切分和抽象,多人協(xié)作的時候如何處理依賴并明確自己的功能點(diǎn)。

關(guān)于DOM屬性、HTML屬性和組件屬性

在React中所有數(shù)據(jù)均掛載在props下,Vue則不然,僅屬性就有三種:組件屬性props,普通html屬性attrs和DOM屬性domProps。在Angular的文檔中關(guān)于插值綁定部分是重點(diǎn)說明了DOM屬性和HTML屬性的區(qū)別,在大多數(shù)情況下兩者都有對應(yīng)的同名屬性,也就是1:1映射關(guān)系,但是也有例外的情況,比如HTML中colspan,DOM中的textContent。HTML屬性的值指定了初始值,并且不能改變,而DOM屬性的值表示當(dāng)前值,是可以改變的。

然后在Vue的模板語法中是不區(qū)分DOM屬性和HTML屬性的,例如:

<template>
 <div>
 <div>輸入的值:{{ title }}</div>
 <input type="text" value="我是DOM屬性值" v-model="title" @input="logTitle" />
 </div>
</template>

<script>
export default {
 data() {
 return {
  title: ''
 }
 },
 
 methods: {
 logTitle(e) {
  // 輸出DOM屬性
  console.log(e.target.value)
  // 輸出HTML屬性
  console.log(e.target.getAttribue('value'))
 }
 }
}
</script>

運(yùn)行示例可以看到input的初始值被設(shè)置為了“我是DOM屬性值",當(dāng)我們在輸入框中添加或者刪除文字時,HTML屬性始終沒有變化,而綁定的DOM值一值在變動。然后再看一下在jsx中的實(shí)現(xiàn):

<div>輸入值:{ this.title }</div>
<input type="text" value="我是DOM屬性" v-model={this.title} onInput={this.logTitle} />

同樣運(yùn)行后會發(fā)現(xiàn)在jsx寫法中并沒有直接將HTML屬性初始化為DOM屬性值,即輸入框中當(dāng)前值為空字符串,這符合預(yù)期的行為。

此外在模板語法中是無法區(qū)分HTML屬性和DOM屬性命名一樣的場景,但是在jsx中可以很好的區(qū)分:

<Demo title="我是組件屬性" domPropsTitle="我是DOM屬性" />

結(jié)果會就是在HMTL中顯示title="我是DOM屬性,而"我是組件屬性”傳遞給了組件。

在React中CSS的樣式寫義在jsx中的語法是以className="xx"的形式,而在Vue的jsx中可以直接寫成class="xx"。實(shí)際上由于class是Js的保留字,因此在DOM中其屬性名為className而在HTML屬性中為class,我們可以在Vue中這樣寫,經(jīng)過Babel轉(zhuǎn)譯后得到正確的樣式類名:

<div domPropsClassName="mt__xs"></div>

注意:如果同時寫了class="xx" domPropsClassName="yy"那么后者的優(yōu)先級較高,和位置無關(guān)。所以盡量還是采用class的寫法。

有使用過Bootstrap經(jīng)驗(yàn)的可能會注意到它里面包含了很多ARIA屬性,這些屬性并不屬于DOM,在jsx中可以通過attrsXX或者直接aria-xx的方式來添加:

<label aria-label="title"></label>
<label attrsAria-label="title"></label>

但是上面的換成domPropsAria-label就沒有任何效果。

注意:在jsx中所有DOM屬性(Property)語法為domPropsXx, HTML特性(Attribute)語法為attrsXx。更多的時候建議還是少使用,或者說合理使用。

在jsx中還可以使用混用的寫法,例如在組件中寫了<Demo title="demo" />,還可以定義一個屬性對象,然后使用{...props}的方式寫在一起,這個時候就會出現(xiàn)屬性合并的問題,同樣的事件多個地方聲明事件處理函數(shù),都會觸發(fā)。

最后需要提及一點(diǎn)的是,在Vue中當(dāng)給一個組件傳了很多props,但是有的并不是組件聲明的,也有可能是一些通用的HTML或者DOM屬性,但是在最終編譯后的HTML中會直接顯示這些props,如果不希望這些屬性顯示在最終的HTML中,可以在組件中設(shè)inheritAttrs: false。雖然不顯示了,但是我們依然可以通過vm.$attrs獲取所有(除class和style)綁定的屬性,包括不在props中定義的。

關(guān)于事件

前面已經(jīng)把事件相關(guān)的知識點(diǎn)都介紹了,這里主要是提及一下關(guān)于jsx事件綁定語法onXx和組件屬性(主要是函數(shù)prop)以on開頭的情況如何處理。

雖然在寫組件的時候可以避開命名以on開頭,但是在使用第三庫的時候,如果遇到了該如何處理呢?比如Element組件Upload很多鉤子都是以on開頭。 下面提供兩種解決辦法:

1.使用展開

<el-upload {...{
 props: {
 onPreview: this.handlePreview
 }
}} />

使用propsXx

<el-upload propsOnPreview={this.handlePreview} />

推薦使用第二種方式,寫起來要簡單些。

復(fù)雜邏輯條件判斷

在模板語法中可以使用v-if、v-else-if和v-else來做條件判斷。在jsx中可以通過?:三元運(yùn)算符(Ternary operator)運(yùn)算符來做if-else判斷:

const Demo = () => isTrue ? <p>True!</p> : null

然后可以利用&&運(yùn)算符的特性簡寫為:

const Demo = () => isTrue && <p>True!</p>

對于復(fù)雜的條件判斷,例如:

const Demo = () => (
 <div>
  {flag && flag2 && !flag3
  ? flag4
   ? <p>Blash</p>
  : flag5
   ? <p>Meh</p>
  : <p>hErp</p>
  : <p>Derp</p>
 }
 </div>
)

可以采用兩種方式來降低判斷識別的復(fù)雜度

  • 最好的辦法:將判斷邏輯轉(zhuǎn)移到子組件

  • 可選的hacky方法:使用IIFE(立即執(zhí)行表達(dá)式)

  • 使用第三方庫解決:jsx-control-statements

下面是使用IIFE通過內(nèi)部使用if-else返回值來優(yōu)化上述問題:

const Demo = () => (
 <div>
 {
  (() => {
  if (flag && flag2 &&!flag3) {
   if (flag4) {
   return <p>Blah</p>
   } else if (flag5) {
   return <p>Meh</p>
   } else {
   return <p>Herp</p>
   }
  } else {
   return <p>Derp</p>
  }
  })()
 }
 </div>
)

還可以使用do表達(dá)式,但是需要插件@babel/plugin-proposal-do-expressions的轉(zhuǎn)譯來支持,

const Demo = () => (
 <div>
 {
  do {
  if (flag1 && flag2 && !flag3) {
   if (flag4) {
   <p>Blah</p>
   } else if (flag5) {
   <p>Meh</p>
   } else {
   <p>Herp</p>
   }
  } else {
   <p>Derp</p>
  }
  }
 }
 </div>
)

再就是一種比較簡單的可選辦法,如下:

const Demo = () => {
 const basicCondition = flag && flag1 && !flag3;
 if (!basicCondition) return <p>Derp</p>
 if (flag4) return <p>Blah</p>
 if (flag5) return <p>Meh</p>
 return <p>Herp</p>
}

最后一種使用jsx插件的就不詳述和舉例了,有興趣的可以直接查看文檔。

組件的傳值

在單個jsx文件中可以寫很多函數(shù)式組件來切分更小的粒度,例如之前的文章Vue后臺管理系統(tǒng)開發(fā)日常總結(jié)__組件PageHeader,組件的形態(tài)有兩種,一種是普通標(biāo)題,另一種是帶有選項(xiàng)卡的標(biāo)題,那么在寫的時候就可以這樣寫:

render() {
 // partial html
 const TabHeader = (
  <div class="page-header page-header--tab"></div>
 )
 
 // function partial
 const Header = () => (
  <div class="page-header"></div>
 )
 
 <div class="page-header">
  {this.withTab ? TabHeader : <Header/>}
 </div>
}

注意在拆分的時候,如果不需要做任何判斷可以純粹是HTML片段賦值給變量,如果需要條件判斷就使用函數(shù)式組件的方式來寫。需要注意的是由于render函數(shù)會多次被調(diào)用,寫的時候注意一下對性能的影響,目前能力有限這方面就不作展開了。

既然使用函數(shù)式組件,那么同樣可以在函數(shù)中傳遞參數(shù)了,參數(shù)是一個對象中,包含了以下屬性

children  # VNode數(shù)組,類似于React的children
data   # 綁定的屬性
 attrs  # Attribute
 domProps # DOM property
 on    # 事件
injections # 注入的對象
listeners: # 綁定的事件類型
 click   # 點(diǎn)擊事件
 ...
parent   # 父組件
props    # 屬性
scopedSlots # 對象,作用域插槽,使用中發(fā)現(xiàn)作用域插槽也掛在這個下面
slots    # 函數(shù),插槽

雖然可以在函數(shù)式組件中傳參數(shù)、事件、slot但是個人覺得不建議這樣做,反而搞復(fù)雜了。

render() {
 const Demo = props => {
 return (
  <div>
   <h4>Jsx中的內(nèi)部組件 { props.data.title }</h4>
  { props.children }
  <br />
  { props.scopedSlots.bar() }
  </div>
 )
 }
 
 return (
  <div>
  <Demo title="test" attrsA="a" domPropsB="b" onClick={this.demo}>
   <h4>我是Children</h4>
  <template slot="bar">
   <p>我是Slot內(nèi)容</p>
  </template>
  </Demo>
 </div>
 )
}

上面的示例最終生成的HTML中會將<template>的內(nèi)容轉(zhuǎn)換為#document-fragment。

以上是“Vue中jsx不完全應(yīng)用的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI