這篇文章主要介紹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ě) 在父組件中使用: 在上面的代碼中我們實(shí)際上使用解構(gòu)的方式來(lái)取得injectedProps,基于解構(gòu)的特性還可以重命名屬性名,在prop為undefined的時(shí)候指定初始值。 如果組件只有一個(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中同樣使用呢? 然后在父組件中以jsx使用: 指令 這里需要注意的是在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ù)格式 過(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)。 在模板中的用法如下: 在jsx中使用方法為: 注意:由于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): 同樣運(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ě)了 最后需要提及一點(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判斷: True! 然后可以利用&&運(yùn)算符的特性簡(jiǎn)寫(xiě)為: True! 對(duì)于復(fù)雜的條件判斷,例如: Blash Meh hErp Derp 可以采用兩種方式來(lái)降低判斷識(shí)別的復(fù)雜度 最好的辦法:將判斷邏輯轉(zhuǎn)移到子組件 可選的hacky方法:使用IIFE(立即執(zhí)行表達(dá)式) 使用第三方庫(kù)解決:jsx-control-statements 下面是使用IIFE通過(guò)內(nèi)部使用if-else返回值來(lái)優(yōu)化上述問(wèn)題: Blah Meh Herp Derp 還可以使用do表達(dá)式,但是需要插件@babel/plugin-proposal-do-expressions的轉(zhuǎn)譯來(lái)支持, Blah Meh Herp Derp 再就是一種比較簡(jiǎn)單的可選辦法,如下: Derp Blah Meh 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ě): 注意在拆分的時(shí)候,如果不需要做任何判斷可以純粹是HTML片段賦值給變量,如果需要條件判斷就使用函數(shù)式組件的方式來(lái)寫(xiě)。需要注意的是由于render函數(shù)會(huì)多次被調(diào)用,寫(xiě)的時(shí)候注意一下對(duì)性能的影響,目前能力有限這方面就不作展開(kāi)了。 既然使用函數(shù)式組件,那么同樣可以在函數(shù)中傳遞參數(shù)了,參數(shù)是一個(gè)對(duì)象中,包含了以下屬性 雖然可以在函數(shù)式組件中傳參數(shù)、事件、slot但是個(gè)人覺(jué)得不建議這樣做,反而搞復(fù)雜了。 我是Slot內(nèi)容 上面的示例最終生成的HTML中會(huì)將的內(nèi)容轉(zhuǎn)換為#document-fragment。 以上是“Vue中jsx不完全應(yīng)用的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!// 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 (
injectedProps.user
{
directives:{
focus: {
inserted: function(el) {
el.focus()
}
}
},
render() {
const directives = [
{ name: 'focus', value: true }
]
return (
{{ message | capitalize }}
const Demo = () => isTrue ?
const Demo = () => isTrue &&
const Demo = () => (
const Demo = () => (
const Demo = () => (
const Demo = () => {
const basicCondition = flag && flag1 && !flag3;
if (!basicCondition) return
render() {
// partial html
const TabHeader = (
)
// function partial
const Header = () => (
)
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ù),插槽
render() {
const Demo = props => {
return (
Jsx中的內(nèi)部組件 { props.data.title }
{ props.children }
{ props.scopedSlots.bar() }
我是Children
網(wǎng)站標(biāo)題:Vue中jsx不完全應(yīng)用的示例分析
地址分享:http://weahome.cn/article/iijeec.html