真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

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

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

為榆樹(shù)等地區(qū)用戶(hù)提供了全套網(wǎng)頁(yè)設(shè)計(jì)制作服務(wù),及榆樹(shù)網(wǎng)站建設(shè)行業(yè)解決方案。主營(yíng)業(yè)務(wù)為網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計(jì)、榆樹(shù)網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專(zhuān)業(yè)、用心的態(tài)度為用戶(hù)提供真誠(chéng)的服務(wù)。我們深信只要達(dá)到每一位用戶(hù)的要求,就會(huì)得到認(rèn)可,從而選擇與我們長(zhǎng)期合作。這樣,我們也可以走得更遠(yuǎn)!

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

渲染函數(shù)想必平時(shí)幾乎沒(méi)有人去寫(xiě),因?yàn)閷?xiě)起來(lái)很痛苦(本人也沒(méi)有寫(xiě)過(guò))。更多的是在Vue中使用JSX語(yǔ)法。寫(xiě)法上和在React中差不多,但是功能上還是沒(méi)有React中那么完善。

在寫(xiě)JSX的過(guò)程中不得考慮一個(gè)樣式的問(wèn)題,雖然可以直接在.vue文件中不寫(xiě)部分,只寫(xiě)

在父組件中使用:


 
  
{{ injectedProps.user.firstName }}
  Log Full Name  

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


 {{ user.firstName }}

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

上面介紹了很多插槽相關(guān)的知識(shí)點(diǎn)足已說(shuō)明其在開(kāi)發(fā)過(guò)程中的重要性。說(shuō)了很多在模板中如何定義和使用作用域插槽,現(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 (
  
  {this.$scopedSlots.subTitle({    injectedProps: this.slotProps   })}   
 )  } }

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

 (
  
   

injectedProps.user

  Log Full Name   
 )  } }}>

指令

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

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

1 直接使用對(duì)象傳遞所有指令屬性

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

{
 directives:{
 focus: {
  inserted: function(el) {
  el.focus()
  }
 }
 },
 
 render() {
 const directives = [
  { name: 'focus', value: true }
 ]
  
 return (
  
      
 )  } }

過(guò)濾器

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

在模板中的用法如下:


{{ message | capitalize }}


在jsx中使用方法為:

{this.$options.filters('formatDate')('2019-07-01')}

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

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

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

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

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

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



運(yùn)行示例可以看到input的初始值被設(shè)置為了“我是DOM屬性值",當(dāng)我們?cè)谳斎肟蛑刑砑踊蛘邉h除文字時(shí),HTML屬性始終沒(méi)有變化,而綁定的DOM值一值在變動(dòng)。然后再看一下在jsx中的實(shí)現(xiàn):

輸入值:{ this.title }

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

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

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

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

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

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


但是上面的換成domPropsAria-label就沒(méi)有任何效果。

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

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

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

關(guān)于事件

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

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

1.使用展開(kāi)

使用propsXx

推薦使用第二種方式,寫(xiě)起來(lái)要簡(jiǎn)單些。

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

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

const Demo = () => isTrue ? 

True!

 : null

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

const Demo = () => isTrue && 

True!

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

const Demo = () => (
 
  {flag && flag2 && !flag3   ? flag4    ? 

Blash

  : flag5    ? 

Meh

  : 

hErp

  : 

Derp

 }  
)

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

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

const Demo = () => (
 
 {   (() => {   if (flag && flag2 &&!flag3) {    if (flag4) {    return 

Blah

   } else if (flag5) {    return 

Meh

   } else {    return 

Herp

   }   } else {    return 

Derp

  }   })()  }  
)

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

const Demo = () => (
 
 {   do {   if (flag1 && flag2 && !flag3) {    if (flag4) {    

Blah

   } else if (flag5) {    

Meh

   } else {    

Herp

   }   } else {    

Derp

  }   }  }  
)

再就是一種比較簡(jiǎn)單的可選辦法,如下:

const Demo = () => {
 const basicCondition = flag && flag1 && !flag3;
 if (!basicCondition) return 

Derp

 if (flag4) return 

Blah

 if (flag5) return 

Meh

 return 

Herp

}

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

組件的傳值

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

render() {
 // partial html
 const TabHeader = (
  
 )    // function partial  const Header = () => (     )       {this.withTab ? TabHeader : 
}   }

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

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

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

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

render() {
 const Demo = props => {
 return (
  
   

Jsx中的內(nèi)部組件 { props.data.title }

  { props.children }      { props.scopedSlots.bar() }   
 )  }    return (   
      

我是Children

      

我是Slot內(nèi)容

       
 ) }

上面的示例最終生成的HTML中會(huì)將