整理的一些 Vue3 知識(shí)點(diǎn),初學(xué)者看完就能上手做項(xiàng)目
點(diǎn)擊上方關(guān)注?前端技術(shù)江湖,一起學(xué)習(xí),天天進(jìn)步
看完你就基本可以上手搞開(kāi)發(fā)了,本文適合Vue初學(xué)者,或者Vue2遷移者,當(dāng)然還是建議Vue3官網(wǎng)完全過(guò)一遍。不適合精通原理,源碼的大佬們。
先推薦兩個(gè)vscode插件
Volar
首先推薦Volar,使用vscode開(kāi)發(fā)Vue項(xiàng)目的小伙伴肯定都認(rèn)識(shí)Vetur這個(gè)神級(jí)插件,有了它可以讓我們得開(kāi)發(fā)如魚(yú)得水。那么Volar可以理解為Vue3版本的Vetur,代碼高亮,語(yǔ)法提示,基本上Vetur有的它都有。
特色功能
當(dāng)然作為新的插件出山,肯定有它獨(dú)有的功能。
多個(gè)根節(jié)點(diǎn)編輯器不會(huì)報(bào)錯(cuò)
Vue3是允許我們有多個(gè)根節(jié)點(diǎn)的,但是我們?nèi)绻褂肰etur就會(huì)報(bào)錯(cuò),不會(huì)影響運(yùn)行,但是看起來(lái)就很煩。所以當(dāng)我們轉(zhuǎn)向Volar那么就不會(huì)出現(xiàn)這個(gè)問(wèn)題了。

編輯器分隔
即便Vue的組件化開(kāi)發(fā),可以將單文件的代碼長(zhǎng)度大幅縮短,但還是動(dòng)輒幾百行甚是上千行。那么我們切換template,script和style的時(shí)候就要頻繁上下翻,雖然有的插件可以直接定位到css,但是你回不去啊!所以這個(gè)功能簡(jiǎn)直是太人性化了。
安裝完Volar以后,打開(kāi)一個(gè).vue文件,看vscode的右上角,有這么一個(gè)圖標(biāo),點(diǎn)一下。

它就會(huì)自動(dòng)給你分隔成三個(gè)頁(yè)面,分別對(duì)應(yīng)template,script和style,這樣就太舒服了有沒(méi)有。

Vue 3 Snippets
推薦的第二個(gè)插件叫做Vue 3 Snippets,同樣的,他也有自己的Vue2版本。它是干什么的呢,可以看一下下面這張圖,我只輸入了“v3”,它有很多提示,我們就先選擇v3computed,選中回車(chē)即可。

然后它就給自動(dòng)給我們寫(xiě)了如下代碼

是不是超級(jí)省事,摸魚(yú)的時(shí)間又增加了!還有更多有趣的使用方式,小伙伴們自行探索吧。
創(chuàng)建Vue3項(xiàng)目
那么正式開(kāi)始學(xué)習(xí)我們的Vue3,先從創(chuàng)建項(xiàng)目開(kāi)始。
使用 vue-cli 創(chuàng)建
輸入下面的命令然后選擇配置項(xiàng)進(jìn)行安裝即可,這里注意vue-cli的版本一定要在4.5.0以上
//?安裝或者升級(jí)
npm?install?-g?@vue/cli
//查看版本?保證?vue?cli?版本在?4.5.0?以上
vue?--version
//?創(chuàng)建項(xiàng)目
vue?create?my-project
//然后根據(jù)提示一步一步傻瓜式操作就行了
...
復(fù)制代碼
使用 Vite 創(chuàng)建
都說(shuō)Vue3.0和Vite2更配,各種優(yōu)化,各種快,但都不屬于本文的內(nèi)容,本文的目的我們只需要知道它特別好用,怎么用就行了。我這里是多選擇了TS,每行都有注釋?zhuān)荒苛巳弧?/p>
//?初始化viete項(xiàng)目
npm?init?vite-app?
//?進(jìn)入項(xiàng)目文件夾
cd?
//?安裝依賴(lài)
npm?install
//啟動(dòng)項(xiàng)目
npm?run?dev
復(fù)制代碼
創(chuàng)建完以后我們先來(lái)看看入口文件main.ts
//?引入createApp函數(shù),創(chuàng)建對(duì)應(yīng)的應(yīng)用,產(chǎn)生應(yīng)用的實(shí)例對(duì)象
import?{?createApp?}?from?'vue';
//?引入app組件(所有組件的父級(jí)組件)
import?App?from?'./App.vue';
//?創(chuàng)建app應(yīng)用返回對(duì)應(yīng)的實(shí)例對(duì)象,調(diào)用mount方法進(jìn)行掛載??掛載到#app節(jié)點(diǎn)上去
createApp(App).mount('#app');
復(fù)制代碼
然后看看根組件app.vue
//Vue2組件中的html模板中必須要有一對(duì)根標(biāo)簽,Vue3組件的html模板中可以沒(méi)有根標(biāo)簽
??<img?alt="Vue?logo"?src="./assets/logo.png">
??
??<HelloWorld?msg="Welcome?to?Your?Vue.js?+?TypeScript?App"?/>
template>
<script?lang="ts">
//?這里可以書(shū)寫(xiě)TS代碼
//?defineComponent函數(shù),目的是定義一個(gè)組件?內(nèi)部可以傳入一個(gè)配置對(duì)象
import?{?defineComponent?}?from?'vue';
//引入子級(jí)組件
import?HelloWorld?from?'./components/HelloWorld.vue';
//?暴露出去一個(gè)定義好的組件
export?default?defineComponent({
??//?當(dāng)前組件的名字
??name:?'App',
??//?注冊(cè)組件
??components:?{
????//?注冊(cè)一個(gè)子級(jí)組件
????HelloWorld,
??},
});
script>
復(fù)制代碼
Composition API
接下來(lái)到了重頭戲,Vue3的招牌特性,Composition API
關(guān)于Composition API這里有大佬做的動(dòng)畫(huà)演示,極力推薦。
那個(gè)忙了一夜的Vue3動(dòng)畫(huà)很好,就是太短了
Composition API可以更方便的抽取共通邏輯,但是不要過(guò)于在意邏輯代碼復(fù)用,以功能提取代碼也是一種思路。
順便提一句,Vue3兼容大部分Vue2語(yǔ)法,所以在Vue3中書(shū)寫(xiě)Vue2語(yǔ)法是沒(méi)有問(wèn)題的(廢除的除外),但是既然我們已經(jīng)升級(jí)Vue3了,不建議混合使用,除非一些大型特殊項(xiàng)目需要兼容兩個(gè)版本。
setup
setup是組合Composition API中的入口函數(shù),也是第一個(gè)要使用的函數(shù)。
setup只在初始化時(shí)執(zhí)行一次,所有的Composition API函數(shù)都在此使用。
setup()?{
??console.log('我執(zhí)行了')?//我執(zhí)行了
},
復(fù)制代碼
可以通過(guò)console.log看到setup是在beforeCreate生命周期之前執(zhí)行的(只執(zhí)行一次)
??beforeCreate()?{
????console.log('beforeCreate執(zhí)行了');
??},
??setup()?{
????console.log('setup執(zhí)行了');
????return?{};
??},
??//setup執(zhí)行了
??//beforeCreate執(zhí)行了
復(fù)制代碼
由此可以推斷出setup執(zhí)行的時(shí)候,組件對(duì)象還沒(méi)有創(chuàng)建,組件實(shí)例對(duì)象this還不可用,此時(shí)this是undefined, 不能通過(guò)this來(lái)訪問(wèn)data/computed/methods/props。
返回對(duì)象中的屬性會(huì)與data函數(shù)返回對(duì)象的屬性合并成為組件對(duì)象的屬性,返回對(duì)象中的方法會(huì)與methods中的方法合并成功組件對(duì)象的方法,如果有重名,?setup優(yōu)先。因?yàn)樵?code style="margin-right: 2px;margin-left: 2px;padding: 2px 4px;outline: 0px;max-width: 100%;font-size: 14px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;border-radius: 4px;color: rgb(233, 105, 0);background-color: rgb(248, 248, 248);box-sizing: border-box !important;overflow-wrap: break-word !important;">setup中this不可用,methods中可以訪問(wèn)setup提供的屬性和方法, 但在setup方法中不能訪問(wèn)data和methods里的內(nèi)容,所以還是不建議混合使用。
setup函數(shù)如果返回對(duì)象, 對(duì)象中的?屬性?或?方法?,?模板?中可以直接使用
//templete
{{number}}</div>
//JS
setup()?{
??const?number?=?18;
??return?{
????number,
??};
},
復(fù)制代碼
注意:setup不能是一個(gè)async函數(shù): 因?yàn)榉祷刂挡辉偈?code style="margin-right: 2px;margin-left: 2px;padding: 2px 4px;outline: 0px;max-width: 100%;font-size: 14px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;border-radius: 4px;color: rgb(233, 105, 0);background-color: rgb(248, 248, 248);box-sizing: border-box !important;overflow-wrap: break-word !important;">return的對(duì)象, 而是promise, 模板中就不可以使用return中返回對(duì)象的數(shù)據(jù)了。
setup的參數(shù)(props,context)`
props: 是一個(gè)對(duì)象,里面有父級(jí)組件向子級(jí)組件傳遞的數(shù)據(jù),并且是在子級(jí)組件中使用props接收到的所有的屬性
context:上下文對(duì)象,可以通過(guò)es6語(yǔ)法解構(gòu)?setup(props, {attrs, slots, emit})
attrs: 獲取當(dāng)前組件標(biāo)簽上所有沒(méi)有通過(guò)props接收的屬性的對(duì)象, 相當(dāng)于?this.$attrs slots: 包含所有傳入的插槽內(nèi)容的對(duì)象, 相當(dāng)于?this.$slots emit: 用來(lái)分發(fā)自定義事件的函數(shù), 相當(dāng)于?this.$emit
演示attrs和props
//父組件
??<child?:msg="msg"?msg2='哈哈哈'?/>
</template>
//子組件
??子組件
??msg:{{?msg?}}
復(fù)制代碼
演示emit
//父組件
??<child?@show="show"?/>
</template>
//子組件
??
????
????
?????????????????class="looklook">
????????看看我出現(xiàn)在了哪里
????????
??????
????
??
復(fù)制代碼
可以看到在子組件中的looklook元素跑到了body下面,而之前的位置默認(rèn)出現(xiàn)了兩行注釋

微信截圖_20210623170701.png Suspense(不確定的)
作用
它們?cè)试S我們的應(yīng)用程序在等待異步組件時(shí)渲染一些后備內(nèi)容,可以讓我們創(chuàng)建一個(gè)平滑的用戶(hù)體驗(yàn)
語(yǔ)法
?
????<template?v-slot:default>
??????
??????<AsyncComp?/>
????template>
????<template?v-slot:fallback>
??????
??????<h1>LOADING...h1>
????template>
??</Suspense>
復(fù)制代碼
vue3中引入異步組件的方式
const?AsyncComp?=?defineAsyncComponent(()?=>?import('./AsyncComp.vue'))
復(fù)制代碼
代碼演示
父組件
??<Suspense>
?????
????<template?v-slot:default>
??????<AsyncComp/>
????template>
????<template?v-slot:fallback>
??????<h1>LOADING...h1>
????template>
??Suspense>
</template>
復(fù)制代碼
子組件
??<h2>AsyncComp22h2>
??<p>{{msg}}p>
</template>
復(fù)制代碼
子組件
??<span?@click="sonClick">msg:?{{?props.msg?}}span>
</template>
復(fù)制代碼
子組件先不使用語(yǔ)法糖
??<div>
????我是子組件{{msg}}
??div>
</template>
復(fù)制代碼
子組件
??<div>
????我是子組件{{?msg?}}
??div>
??<button?@click="handleClick(1)">我是按鈕1button>
??<button?@click="handleClick(2)">我是按鈕2button>
</template>
復(fù)制代碼
子組件1
??<div>
????我是子組件1
????<h1>{{msg}}h1>
??div>
</template>
復(fù)制代碼
子組件2
??<div>
????我是子組件2
??div>
??<button?@click='changeMsg'>點(diǎn)擊修改msgbutton>
</template>
復(fù)制代碼
演示

1.gif 自定義指令
先看看Vue2自定義指令的鉤子
bind:當(dāng)指令綁定在對(duì)應(yīng)元素時(shí)觸發(fā)。只會(huì)觸發(fā)一次。 inserted:當(dāng)對(duì)應(yīng)元素被插入到?DOM?的父元素時(shí)觸發(fā)。 update:當(dāng)元素更新時(shí),這個(gè)鉤子會(huì)被觸發(fā)(此時(shí)元素的后代元素還沒(méi)有觸發(fā)更新)。 componentUpdated:當(dāng)整個(gè)組件(包括子組件)完成更新后,這個(gè)鉤子觸發(fā)。 unbind:當(dāng)指令被從元素上移除時(shí),這個(gè)鉤子會(huì)被觸發(fā)。也只觸發(fā)一次。
在?Vue3?中,官方為了更有助于代碼的可讀性和風(fēng)格統(tǒng)一,把自定義指令的鉤子名稱(chēng)改的更像是組件生命周期,盡管他們是兩回事
bind?=>?beforeMount inserted?=>?mounted beforeUpdate:?新的鉤子,會(huì)在元素自身更新前觸發(fā) update?=>?移除! componentUpdated?=>?updated beforeUnmount:?新的鉤子,當(dāng)元素自身被卸載前觸發(fā) unbind?=>?unmounted
過(guò)渡動(dòng)畫(huà)
這個(gè)沒(méi)有什么大的改動(dòng),只是修改了兩個(gè)class名字,正是因?yàn)闆](méi)有什么大的改動(dòng),導(dǎo)致我曾經(jīng)在這里栽了大跟頭,寫(xiě)完了怎么都不對(duì),后來(lái)查官網(wǎng)才知道。
以下是直接引用?官網(wǎng)的原文
v-enter-from:定義進(jìn)入過(guò)渡的開(kāi)始狀態(tài)。在元素被插入之前生效,在元素被插入之后的下一幀移除。
v-enter-active:定義進(jìn)入過(guò)渡生效時(shí)的狀態(tài)。在整個(gè)進(jìn)入過(guò)渡的階段中應(yīng)用,在元素被插入之前生效,在過(guò)渡/動(dòng)畫(huà)完成之后移除。這個(gè)類(lèi)可以被用來(lái)定義進(jìn)入過(guò)渡的過(guò)程時(shí)間,延遲和曲線函數(shù)。
v-enter-to:定義進(jìn)入過(guò)渡的結(jié)束狀態(tài)。在元素被插入之后下一幀生效 (與此同時(shí) v-enter-from 被移除),在過(guò)渡/動(dòng)畫(huà)完成之后移除。
v-leave-from:定義離開(kāi)過(guò)渡的開(kāi)始狀態(tài)。在離開(kāi)過(guò)渡被觸發(fā)時(shí)立刻生效,下一幀被移除。
v-leave-active:定義離開(kāi)過(guò)渡生效時(shí)的狀態(tài)。在整個(gè)離開(kāi)過(guò)渡的階段中應(yīng)用,在離開(kāi)過(guò)渡被觸發(fā)時(shí)立刻生效,在過(guò)渡/動(dòng)畫(huà)完成之后移除。這個(gè)類(lèi)可以被用來(lái)定義離開(kāi)過(guò)渡的過(guò)程時(shí)間,延遲和曲線函數(shù)。
v-leave-to:離開(kāi)過(guò)渡的結(jié)束狀態(tài)。在離開(kāi)過(guò)渡被觸發(fā)之后下一幀生效 (與此同時(shí) v-leave-from 被刪除),在過(guò)渡/動(dòng)畫(huà)完成之后移除。
特別注意的是v-enter改成了v-enter-form,v-leave改成了v-leave-from。
其他小知識(shí)
Vue3移除了filter
獲取組件實(shí)例方法getCurrentInstance()
這個(gè)方法可以獲取到當(dāng)前組件的實(shí)例,相當(dāng)于Vue2中的this最后,畢竟是個(gè)人總結(jié),難免會(huì)出現(xiàn)紕漏和錯(cuò)誤,期待各路大神的補(bǔ)充和糾正。
我的開(kāi)源項(xiàng)目:
https://juejin.cn/post/6963945204965441550"
參考資料
[1]https://github.com/vuejs/rfcs/pull/210
作者:一尾流鶯
https://juejin.cn/post/6977004323742220319
The End
歡迎自薦投稿到《前端技術(shù)江湖》,如果你覺(jué)得這篇內(nèi)容對(duì)你挺有啟發(fā),記得點(diǎn)個(gè)?「在看」哦
點(diǎn)個(gè)『在看』支持下?
