Vue3 中可以幫助你早點下班的 9 個開發(fā)技巧!
序
vue3也發(fā)布很長時候了,官方也將默認(rèn)版本切換為vue3,而且也出現(xiàn)了完善的中文文檔[1],不知同志們是否已經(jīng)使用了了呢?
本渣體驗了一段時間,還是相當(dāng)?shù)慕z滑,些許開發(fā)經(jīng)驗奉上,望大家能早點下班
也可以看下 源碼解析github vue-next-analysis[2](未完待續(xù)持續(xù)更新中....)
善用h(createVNode)和render 函數(shù)
我們知道在vue3中導(dǎo)出了一個神奇的createVNode 函數(shù) 當(dāng)前函數(shù)它能創(chuàng)建一個vdom,大家不要小看vdom, 我們好好利用它,就能做出意想不到的效果比如我們要實現(xiàn)一個彈窗組件
我們通常的思路是寫一個組件在項目中引用進來,通過v-model來控制他的顯示隱藏,但是這樣有個問題,我們復(fù)用的時候的成本需要復(fù)制粘貼。我們沒有辦法來提高效率,比如封裝成npm 通過調(diào)用js來使用。
然而,有了 createVNode 和render 之后所有問題就迎刃而解了
//?我們先寫一個彈窗組件
????????const?message?=?{
????????????setup()?{
????????????????const?num?=?ref(1)
????????????????return?{
????????????????????num
????????????????}
????????????},
????????????template:?`
????????????????????????{{num}}
????????????????????????這是一個彈窗
??????????????????????`
????????}
復(fù)制代碼
??//?初始化組件生成vdom
??const?vm?=?createVNode(message)
??//?創(chuàng)建容器,也可以用已經(jīng)存在的
??const?container?=?document.createElement('div')
??//render通過patch?變成dom
??render(vm,?container)
//?彈窗掛到任何你想去的地方??
document.body.appendChild(container.firstElementChild)
復(fù)制代碼
經(jīng)過上面這一通騷操作,我們發(fā)現(xiàn)我們可以將他封裝為一個方法,放到任何想放的地方。
善用JSX/TSX
文檔上說了,在絕大多數(shù)情況下,Vue 推薦使用模板語法來搭建 HTML。然而在某些使用場景下,我們真的需要用到 JavaScript 完全的編程能力。這時渲染函數(shù)就派上用場了。
jsx和模板語法的優(yōu)勢對比
jsx和模板語法都是vue 支持的的書寫范疇,然后他們確有不同的使用場景,和方式,需要我們根據(jù)當(dāng)前組件的實際情況,來酌情使用
什么是JSX
JSX 是一種 Javascript 的語法擴展,JSX = Javascript + XML,即在 Javascript 里面寫 XML,因為 JSX 的這個特性,所以他即具備了 Javascript 的靈活性,同時又兼具 html 的語義化和直觀性。
模板語法的優(yōu)勢
1、模板語法書寫起來不怎么違和,我們就像在寫html一樣 2、在vue3中由于模板的可遍歷性,它能在編譯階段做更多優(yōu)化,比如靜態(tài)標(biāo)記、塊block、緩存事件處理程序等 3、模板代碼邏輯代碼嚴(yán)格分開,可讀性高 4、對JS功底不那么好的人,記幾個命令就能快速開發(fā),上手簡單 5、vue官方插件的完美支持,代碼格式化,語法高亮等
JSX的優(yōu)勢
1、靈活、靈活、靈活(重要的事情說三遍)
復(fù)制代碼2、一個文件能寫好多個組件
復(fù)制代碼3、只要JS功底好,就不用記憶那么多命令,上來就是一通輸出
復(fù)制代碼4、JS和JSX混用,方法即聲明即用,對于懂行的人來說邏輯清晰
復(fù)制代碼
對比
由于vue對于JSX的支持,社區(qū)里,也是爭論來爭論去,到底要分個高低,然后本渣認(rèn)為,他倆本來沒有高低,您覺得哪個適合,就用哪個即可,缺點放在對的地方他就是優(yōu)勢 要發(fā)揚咱們老前輩們傳下來的中庸之道,做集大成者,將兩者結(jié)合使用,就能發(fā)揮無敵功效,亂軍之中博老板青睞。
接下來說一下本人的一點粗淺理解,我們知道組件類型,分為容器型組件和展示展示型組件 在一般情況下,容器型組件,他由于可能要對于當(dāng)前展示型組件做一個標(biāo)準(zhǔn)化或者宰包裝,那么此時容器型組件中用JSX就再好不過
舉個例子:現(xiàn)在有個需求,我們有兩個按鈕,現(xiàn)在要做一個通過后臺數(shù)據(jù)來選擇展示哪一個按鈕,我們通常的做法,是通過在一個模板中通過v-if去控制不同的組件
然而有了JSX與函數(shù)式組件之后,我們發(fā)現(xiàn)邏輯更清晰了,代碼更簡潔了,質(zhì)量更高了,也更裝X了
我們來看
先整兩個組件
//btn1.vue
??<div>
??????這是btn1{{?num?}}
??????<slot>slot>
??div>
</template>
復(fù)制代碼
善用依賴注入(Provide / Inject)
在善用依賴注入之前是,我們先來了解一些概念,幫助我們更全面的了解依賴注入的前世今生
IOC 和DI 是什么
控制反轉(zhuǎn)(Inversion of Control,縮寫為IoC),是面向?qū)ο缶幊?/span>[3]中的一種設(shè)計原則,可以用來減低計算機代碼之間的耦合度[4]。其中最常見的方式叫做依賴注入(Dependency Injection,簡稱DI),還有一種方式叫“依賴查找”(Dependency Lookup)。通過控制反轉(zhuǎn),對象在被創(chuàng)建的時候,由一個調(diào)控系統(tǒng)內(nèi)所有對象的外界實體,將其所依賴的對象的引用傳遞(注入)給它。
什么是依賴注入
依賴注入 用大白話來說:就是將實例變量傳入到一個對象中去
vue中的依賴注入
在vue中,我們套用依賴注入的概念,其實就是在父組件中聲明依賴,將他們注入到子孫組件實例中去,可以說是能夠很大程度上代替全局狀態(tài)管理的存在

我們先來看看他的基本用法
父組件中聲明provide
//parent.vue
????<child?@setColor="setColor">child>
????<button?@click="count++">添加button>
</template>
復(fù)制代碼
子組件中注入進來
//child.vue
//使用inject?注入
????<div>這是注入的內(nèi)容{{?count?}}div>
????<child1?v-bind="$attrs">child1>
</template>
?
復(fù)制代碼
正因為依賴注入的特性,我們很大程度上代替了全局狀態(tài)管理,相信誰都不想動不動就引入那繁瑣的vuex吧
接下來我們來舉個例子,現(xiàn)在我么有個頁面主題色,他貫穿所有組件,并且可以在某一些組件內(nèi)更改主題色,那我們常規(guī)的解決方案中,就是裝個vuex然后通過他的api下發(fā)顏色值,這時候如果想改,首先要發(fā)起dispatch到Action ,然后在Action中觸發(fā)Mutation接著在Mutation中再去改state,如此一來,你是不是發(fā)現(xiàn)有點殺雞用牛刀了,我就改個顏色而已!
我們來看有了依賴注入 應(yīng)該怎么處理
首先我們知道vue是單項數(shù)據(jù)流,也就是子組件不能修改父組件的內(nèi)容,于是我們就應(yīng)該想到使用$attrs使用它將方法透傳給祖先組件,在組件組件中修改即可。
我們來看代碼
//子孫組件child1.vue
????<div?:style="`color:${color}`"?@click="setColor">這是注入的內(nèi)容的顏色div>
</template>
復(fù)制代碼
以上代碼參考vue版本的Composition API庫所有完整版請參考[5]
善于使用getCurrentInstance 獲取組件實例
getCurrentInstance?支持訪問內(nèi)部組件實例, 通常情況下他被放在 setup中獲取組件實例,但是 getCurrentInstance?只暴露給高階使用場景,典型的比如在庫中。
強烈反對在應(yīng)用的代碼中使用?getCurrentInstance。請不要把它當(dāng)作在組合式 API 中獲取?this?的替代方案來使用。
那他的作用是什么呢?
還是邏輯提取,用來代替Mixin,這是在復(fù)雜組件中,為了整個代碼的可維護性,抽取通用邏輯這是必須要去做的事情,我們可以看element-plus[6] 中table的復(fù)用邏輯,在邏輯提取中由于涉及獲取props、proxy、emit 以及能通過當(dāng)前組件獲取父子組件的關(guān)系等,此時getCurrentInstance 的作用無可代替
如下element-plus代碼中利用getCurrentInstance 獲取父組件parent中的數(shù)據(jù),分別保存到不同的變量中,我們只需要調(diào)用當(dāng)前useMapState即可拿到數(shù)據(jù)
//?保存數(shù)據(jù)的邏輯封裝
function?useMapState<T>()?{
??const?instance?=?getCurrentInstance()
??const?table?=?instance.parent?as?Table
??const?store?=?table.store
??const?leftFixedLeafCount?=?computed(()?=>?{
????return?store.states.fixedLeafColumnsLength.value
??})
??const?rightFixedLeafCount?=?computed(()?=>?{
????return?store.states.rightFixedColumns.value.length
??})
??const?columnsCount?=?computed(()?=>?{
????return?store.states.columns.value.length
??})
??const?leftFixedCount?=?computed(()?=>?{
????return?store.states.fixedColumns.value.length
??})
??const?rightFixedCount?=?computed(()?=>?{
????return?store.states.rightFixedColumns.value.length
??})
??return?{
????leftFixedLeafCount,
????rightFixedLeafCount,
????columnsCount,
????leftFixedCount,
????rightFixedCount,
????columns:?store.states.columns,
??}
}
復(fù)制代碼
善用$attrs
$attrs?現(xiàn)在包含了_所有_傳遞給組件的 attribute,包括?class?和?style。
$attrs在我們開發(fā)中到底有什么用呢?
通過他,我們可以做組件的事件以及props透傳
首先有一個標(biāo)準(zhǔn)化的組件,一般是組件庫的組件等等
//child.vue
????<div>這是一個標(biāo)準(zhǔn)化組件div>
????<input?type="text"?:value="num"?@input="setInput"?/>
</template>
?
復(fù)制代碼
我們發(fā)現(xiàn)當(dāng)前包裝組件中使用了$attrs,通過他透傳給標(biāo)準(zhǔn)化組件,這樣一來,我們就能對比如element UI中的組件做增強以及包裝處理,并且不用改動原組件的邏輯。
優(yōu)雅注冊全局組件技巧
vue3的組件通常情況下使用vue提供的component 方法來完成全局組件的注冊
代碼如下:
const?app?=?Vue.createApp({})
app.component('component-a',?{
??/*?...?*/
})
app.component('component-b',?{
??/*?...?*/
})
app.component('component-c',?{
??/*?...?*/
})
app.mount('#app')
復(fù)制代碼
使用時
"app">
??<component-a>component-a>
??<component-b>component-b>
??<component-c>component-c>
</div>
復(fù)制代碼
然而經(jīng)過大佬的奇技淫巧的開發(fā),我們發(fā)現(xiàn)可能使用注冊vue插件的方式,也能完成組件注冊,并且是優(yōu)雅的!
vue插件注冊
插件的格式
//plugins/index.js
export?default?{
??install:?(app,?options)?=>?{
??????//?這是插件的內(nèi)容
??}
}
復(fù)制代碼
插件的使用
import?{?createApp?}?from?'vue'
import?Plugin?from?'./plugins/index.js'
const?app?=?createApp(Root)
app.use(Plugin)
app.mount('#app')
復(fù)制代碼
其實插件的本質(zhì),就是在use的方法中調(diào)用插件中的install方法,那么這樣一來,我們就能在install方法中注冊組件。
index.js中拋出一個組件插件
//?index.js
import?component?from?'./Cmponent.vue'
const?component?=?{
????install:function(Vue){
????????Vue.component('component-name',component)
????}??//'component-name'這就是后面可以使用的組件的名字,install是默認(rèn)的一個方法?component-name?是自定義的,我們可以按照具體的需求自己定義名字
}
//?導(dǎo)出該組件
export?default?component
復(fù)制代碼
組件注冊
//?引入組件
import?install?from?'./index.js';?
//?全局掛載utils
Vue.use(install);
復(fù)制代碼
上述案例中,就是一個簡單的優(yōu)雅的組件注冊方式,大家可以發(fā)現(xiàn)包括element-plus、vant 等組件都是用如此方式注冊組件。
善用
?
復(fù)制代碼
子組件中使用 title的props 以及規(guī)定吐出update:title的emit
????<div>{{?title?}}div>
????<input?type="text"?@input="setInput"?/>
</template>
欧美中文字幕在线视频
|
欧美午夜精品久久久久
|
国产91热爆
|
日韩成人午夜福利
|
娇妻4p被八个男人伺候
|
精品毛片
|
男人和女人日b
|
《年轻的女教师》3完整版
|
日韩无码视
|
一日美女青青草
|
