摘要:發(fā)明了,利用語(yǔ)法來(lái)創(chuàng)建虛擬。然而,對(duì)持久化實(shí)例的缺乏也意味著函數(shù)式組件不會(huì)出現(xiàn)在的組件樹(shù)里。這個(gè)很有用,當(dāng)你在父組件給子組件綁定事件時(shí)就需要這個(gè)了。之前考慮過(guò)用動(dòng)態(tài)組件來(lái)切換,但是放棄了,因?yàn)闆](méi)有直觀(guān)啊。另外推薦大家多用函數(shù)式組件提高性能。
什么是JSX?
JSX就是Javascript和XML結(jié)合的一種格式。React發(fā)明了JSX,利用HTML語(yǔ)法來(lái)創(chuàng)建虛擬DOM。當(dāng)遇到<,JSX就當(dāng)HTML解析,遇到{就當(dāng)JavaScript解析.
我為什么要在vue中用JSX?想折騰一下唄,開(kāi)玩笑.最開(kāi)始是因?yàn)榻谠趯W(xué)習(xí)react,在里面體驗(yàn)了一把jsx語(yǔ)法,發(fā)現(xiàn)也并沒(méi)有別人說(shuō)的很難受的感覺(jué)啊,于是就想嘗試在vue中也試下,廢話(huà)不多說(shuō),先來(lái)用代碼來(lái)看下兩者的區(qū)別吧.
ps:vue中大部分場(chǎng)景是不需要用render函數(shù)的,還是用模板更簡(jiǎn)潔直觀(guān).
## 使用template
// item.vue
item組件中就是接收父組件傳過(guò)來(lái)的id值來(lái)顯示不同的h標(biāo)簽,v-if可以說(shuō)用到了"極致",而且寫(xiě)了很多個(gè)冗余的slot
## 使用render函數(shù)和jsx
// item.vue
再加上父組件來(lái)控制props的值。父組件不做對(duì)比還用傳統(tǒng)的template格式,
// list.vueHello World
運(yùn)行后頁(yè)面就渲染出了h1 or h2 or h3標(biāo)簽,同時(shí)slot也只有一個(gè),點(diǎn)擊切換props的值,也會(huì)顯示不同的h標(biāo)簽。第二種寫(xiě)法雖然不是很直接,但是省去了很多冗余代碼,頁(yè)面一下清爽了很多。
## 沒(méi)了v-if,v-for,v-model怎么辦?
不要著急,這些指令只是黑魔法,用js很容易實(shí)現(xiàn)。
v-if
render(){ return ({this.show?"你帥":"你丑"}) }
寫(xiě)三元表達(dá)式只能寫(xiě)簡(jiǎn)單的,那么復(fù)雜的還得用if/else
render(){ let ifText if(this.show){ ifText=你帥
}else{ ifText=你丑
} return ({ifText}) }
v-for
data(){ return{ show:false, list:[1,2,3,4] } }, render(){ return ({this.list.map((v)=>{ return) }{v}
})}
在jsx中{}中間是沒(méi)辦法寫(xiě)if/for語(yǔ)句的只能寫(xiě)表達(dá)式,所以就用map來(lái)當(dāng)循環(huán),用三元表達(dá)式來(lái)當(dāng)判斷了
v-model
最近在幫公司面試招人發(fā)現(xiàn)v-model很多人都不知道語(yǔ)法糖是什么?然后有些人說(shuō)我可以用原生js實(shí)現(xiàn),但是他們竟然不知道在vue中怎么實(shí)現(xiàn),好吧,兩個(gè)點(diǎn):傳值和監(jiān)聽(tīng)事件改變值。
怎么用自定義組件?
很簡(jiǎn)單,只需要導(dǎo)入進(jìn)來(lái),不用再在components屬性聲明了,直接寫(xiě)在jsx中比如
事件,class,style,ref等等怎么綁定?來(lái)看下面的寫(xiě)法
render (h) { return () }
上面有個(gè)地方需要注意,當(dāng)給自定義組件綁定事件時(shí)用nativeOnClick,而模板格式是用
@click.native ,另外當(dāng)用到給函數(shù)式組件綁定事件時(shí)就有點(diǎn)小坑了下面說(shuō)。
函數(shù)式組件無(wú)狀態(tài),無(wú)this實(shí)例,下面是vue文檔中提到的一段話(huà):
因?yàn)楹瘮?shù)式組件只是一個(gè)函數(shù),所以渲染開(kāi)銷(xiāo)也低很多。然而,對(duì)持久化實(shí)例的缺乏也意味著函數(shù)式組件不會(huì)出現(xiàn)在 Vue devtools 的組件樹(shù)里。
我個(gè)人理解因?yàn)闆](méi)了狀態(tài)(data),少了很多響應(yīng)式的處理,還有生命周期等過(guò)程會(huì)提高速度和減少內(nèi)存占用吧?
函數(shù)式組件也可以在模板格式中用只需要這樣
那jsx中的函數(shù)式組件呢?也很簡(jiǎn)單只需增加配置functional: true就可以了
那函數(shù)式組件沒(méi)有了this 實(shí)例怎么綁定事件怎么獲取props呢?組件需要的一切都是通過(guò)上下文傳遞,包括:
props : 提供所有 prop 的對(duì)象
children: VNode 子節(jié)點(diǎn)的數(shù)組
slots: 返回所有插槽的對(duì)象的函數(shù)
data:傳遞給組件的數(shù)據(jù)對(duì)象,并將這個(gè)組件作為第二個(gè)參數(shù)傳入 createElement
上面我只列舉了部分屬性,這些是非函數(shù)式組件的東西,對(duì)于函數(shù)式組件
vue 增加了context對(duì)象,需要作為render(h,context) 第二個(gè)參數(shù)傳入,this.$slots.default更新為context.children props原本是直接掛在this上的,現(xiàn)在變?yōu)?b>context.props掛在了context.props上。this.data變?yōu)榱?b>context.data需要注意的是對(duì)于函數(shù)式組件,沒(méi)有被定義為prop的特性不會(huì)自動(dòng)添加到組件的根元素上,意思就是需要我們手動(dòng)添加到組件根元素了,看個(gè)例子吧
//父組件 ...省略無(wú)關(guān)代碼 render(){ return (- ) } //Item.vue組件 export default { functional:true, name: "item", render(h,context){ return (
{context.props.data}) } }上面代碼期待的是.large類(lèi)名傳入到了Item的根元素上,但是其實(shí)沒(méi)有。我們需要增加點(diǎn)東西
// Item.vue export default { functional:true, name: "item", render(h,context){ return ({context.props.data}) } }注意到,通過(guò)展開(kāi)運(yùn)算符把所有的屬性添加到了根元素上,這個(gè)context.data就是你在父組件給子組件增加的屬性,他會(huì)跟你在子元素根元素的屬性智能合并,現(xiàn)在.large類(lèi)名就傳進(jìn)來(lái)了。這個(gè)很有用,當(dāng)你在父組件給子組件綁定事件時(shí)就需要這個(gè)了。下面說(shuō)一個(gè)關(guān)于綁定事件的小坑
向 createElement 通過(guò)傳入 context.data 作為第二個(gè)參數(shù),我們就把 my-functional-button 上面所有的特性和事件監(jiān)聽(tīng)器都傳遞下去了。事實(shí)上這是非常透明的,那些事件甚至并不要求 .native 修飾符上面是vue官網(wǎng)的一段話(huà),然而我看了一遍就忽略了一句很重要的話(huà),就是最后一句,他說(shuō)不需要.native修飾符了?好先看代碼
// 父組件 methods:{ show(){ alert("你好") } }, render(){ return (- ) }
上面代碼乍一看沒(méi)毛病,自定義組件用onNativeClick嘛,結(jié)果就是不會(huì)彈窗。唉,最后讀了幾遍剛才vue文檔中的解釋?zhuān)虐l(fā)現(xiàn)原來(lái)函數(shù)式組件不需要.native修飾符,對(duì)于template格式肯定一下就反應(yīng)過(guò)來(lái)了,但是jsx的話(huà),好吧,把上面的onNativeClick重新改為onClick就好了。
現(xiàn)有項(xiàng)目哪些功能可以用jsx代替呢?這個(gè)其實(shí)跟最開(kāi)始我例舉的例子很像。我在項(xiàng)目中用它來(lái)干掉了滿(mǎn)屏的v-if/v-else
由于我的業(yè)務(wù)是pad上的,需求是一套試卷有幾十道題目,要求一屏只顯示一道題目,點(diǎn)擊下一題顯示下一個(gè)題,思路也比較簡(jiǎn)單:用一個(gè)num變量表示當(dāng)前正在展示的題目索引
每次點(diǎn)擊下一題按鈕時(shí)num++
用v-if來(lái)判斷 num===1,num===2這樣來(lái)決定展示哪個(gè)。
這一寫(xiě),模板里面好多啊,由于我們的題目每道題的模板可能都不一樣,所以沒(méi)辦法循環(huán),只能手寫(xiě)全部。之前考慮過(guò)用動(dòng)態(tài)組件來(lái)切換,但是放棄了,因?yàn)闆](méi)有if直觀(guān)啊。
下面看怎么用jsx優(yōu)化一下
//父組件 export default { name: "list", data() { return { data:"我是函數(shù)式組件", id:1, tests:{ 1:第一道題, 2:, 3:第二道題 } } }, methods:{ next(){ ++this.id } }, render(){ return (第三道題
) } }上面每道題目的結(jié)構(gòu)都不一致
//子組件,只接受數(shù)據(jù)展示,用函數(shù)式組件上面沒(méi)有用任何if/else判斷就完成了功能,這里用jsx我覺(jué)得比較合適,不知道各位大佬有什么其他思路?
最后本片文章首發(fā)于掘金社區(qū)掘金總結(jié)一下吧,我們平時(shí)開(kāi)發(fā)還是多用temlate因?yàn)橹庇^(guān)簡(jiǎn)潔,各種指令用著很方便,等你覺(jué)得用template寫(xiě)出的代碼看著很冗余,或者想自己控制渲染邏輯比如循環(huán),判斷等等時(shí)可以考慮用JSX。另外推薦大家多用函數(shù)式組件提高性能。
第一次寫(xiě)文章,希望各位花時(shí)間看了的大佬覺(jué)得哪個(gè)說(shuō)的不太嚴(yán)謹(jǐn)還需多多包涵,提出意見(jiàn)我都接受。
參考資料vue 渲染函數(shù)&jsx
babel-plugin-transform-vue-jsx
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/95468.html
摘要:錯(cuò)誤例子可以實(shí)現(xiàn)的語(yǔ)法如下使用邏輯運(yùn)算符文件文件使用三元運(yùn)算符文件使用函數(shù)綁定的數(shù)據(jù)對(duì)象也不必內(nèi)聯(lián)定義在模板里可以定義一個(gè)函數(shù),類(lèi)似中的鉤子函數(shù)。 作者:羽徵 摘要:操作元素的 class 列表和內(nèi)聯(lián)樣式是數(shù)據(jù)綁定的一個(gè)常見(jiàn)需求,頻繁操作dom元素會(huì)降低javascript性能,為了實(shí)現(xiàn)高性能js,動(dòng)態(tài)綁定class和style是高素養(yǎng)程序員的必選。本文以React-JSX語(yǔ)法為基礎(chǔ),...
摘要:錯(cuò)誤例子可以實(shí)現(xiàn)的語(yǔ)法如下使用邏輯運(yùn)算符文件文件使用三元運(yùn)算符文件使用函數(shù)綁定的數(shù)據(jù)對(duì)象也不必內(nèi)聯(lián)定義在模板里可以定義一個(gè)函數(shù),類(lèi)似中的鉤子函數(shù)。 作者:羽徵 摘要:操作元素的 class 列表和內(nèi)聯(lián)樣式是數(shù)據(jù)綁定的一個(gè)常見(jiàn)需求,頻繁操作dom元素會(huì)降低javascript性能,為了實(shí)現(xiàn)高性能js,動(dòng)態(tài)綁定class和style是高素養(yǎng)程序員的必選。本文以React-JSX語(yǔ)法為基礎(chǔ),...
摘要:語(yǔ)法是一種語(yǔ)法的拓展語(yǔ)言,在中官方也推薦使用描述用戶(hù)界面,使用起來(lái)會(huì)比較快捷而且易讀不是一門(mén)新的語(yǔ)言,可以理解為是一種語(yǔ)法糖,作用就是能夠讓我們更加直觀(guān)的在中創(chuàng)建標(biāo)簽,最終還是會(huì)被編譯為語(yǔ)法,例如我們看一段代碼上面的語(yǔ)法最終會(huì)被編譯為語(yǔ)法, Reatc JSX語(yǔ)法 jsx是一種JavaScript語(yǔ)法的拓展語(yǔ)言,在React中官方也推薦使用jsx描述用戶(hù)界面,使用起來(lái)會(huì)比較快捷而且易讀...
摘要:想要使用語(yǔ)法的話(huà),配合,這個(gè)插件,體驗(yàn)更佳,這個(gè)插件在語(yǔ)法中實(shí)現(xiàn)了。這種方式最接近的單文件組件的寫(xiě)法,如果一個(gè)完善項(xiàng)目從改成,用這種方法很快,只要加上和一些必要的變量類(lèi)型就好了,然后用包裹就好。不推薦混入用這種方式寫(xiě),無(wú)法實(shí)現(xiàn)多繼承。 最近嘗試了一下 TypeScript,試著把一個(gè) Vue 項(xiàng)目改成了 TypeScript 的,感覺(jué)還不錯(cuò) 目前 Vue 和 TypeScript 的配...
摘要:項(xiàng)目編碼規(guī)范化工具工具代碼校驗(yàn)工具,讓代碼更一致和避免。在配置文件到項(xiàng)可對(duì)單條規(guī)則一一進(jìn)行改寫(xiě)。以下以項(xiàng)目需校驗(yàn)文件為例參考鏈接一步一步,統(tǒng)一項(xiàng)目中的編碼規(guī)范 Web 項(xiàng)目編碼規(guī)范化工具 工具 ESLint The pluggable linting utility for JavaScript and JSX 代碼校驗(yàn)工具(linting utility),讓代碼更一致和避免 bug...
閱讀 2696·2023-04-26 03:00
閱讀 1489·2021-10-12 10:12
閱讀 4334·2021-09-22 15:33
閱讀 3000·2021-09-22 15:06
閱讀 1597·2019-08-30 15:44
閱讀 2204·2019-08-30 13:59
閱讀 580·2019-08-30 11:24
閱讀 2483·2019-08-29 17:07