Vue面試題
v-html 會有XSS風(fēng)險(xiǎn),會覆蓋子組件
computed 有緩存,data不變則不會重新計(jì)算
watch 默認(rèn)不會深度監(jiān)聽,要deep:true開啟
watch 監(jiān)聽引用類型,拿不到oldVal,因?yàn)橹羔樝嗤藭r(shí)已經(jīng)指向了新的val
style指令需要駝峰式命名方式寫,例如{fontSize: '10px'}
v-if v-else 可使用變量,也可使用===表達(dá)式
-
v-if 和 v-show 的區(qū)別
v-if false不渲染,適合更新不頻繁的,節(jié)省性能
v-show false也渲染
v-for 和 v-if 不能一起使用,v-for 比 v-if 優(yōu)先級高,影響性能
事件的event是原生的event,沒有裝飾過,事件是掛載到當(dāng)前元素
v-for 的 key 因?yàn)?VDOM 的 diff 算法,通過判斷新vnode和舊vnode的key是否相等,從而復(fù)用與新節(jié)點(diǎn)對應(yīng)的老節(jié)點(diǎn),節(jié)約性能開銷
用index做key在diff算法中不起作用,用index拼接其他值會導(dǎo)致節(jié)點(diǎn)不能復(fù)用,所以用唯一值做key,比如數(shù)據(jù)id
-
props 和 $emit
props父組件通過子組件屬性給子組件傳值
$emit子組件綁定父組件方法,在子組件內(nèi)使用$emit觸發(fā)父組件的方法
-
Vue組件如何通訊
父子組件事件props $emit
自定義事件 $emit $on
通過vuex
-
組件間通訊-自定義事件(常用兄弟組件通訊)
Vue自有實(shí)現(xiàn),使用EventBus方式(bus總線機(jī)制/發(fā)布訂閱者模式/觀察者模式)
import Vue from 'vue' var event = new Vue() export default event在A組件內(nèi)使用
event.$emit('onHandle', params)在B組件內(nèi)的mounted中綁定自定義事件
event.$on('onHandle', this.handle)在B組局內(nèi)beforeDestroy中及時(shí)銷毀監(jiān)聽事件,否則可能造成內(nèi)存泄露
event.$off('onHandle', this.handle) -
組件生命周期 <font color="red">* 必須背會</font>
掛載
beforeCreate->create->beforeMount->mountedbeforeCreate里沒有this,實(shí)例還未初始化,在數(shù)據(jù)觀測(data observer)和event/watcher事件配置前
create 初始化示例,沒有渲染,取不到dom,沒有$el,通常初始化某些屬性值
beforeMount 掛載開始之前,相關(guān)渲染首次被調(diào)用
mounted 是渲染完了,通常是初始化頁面完成后,再對html的dom節(jié)點(diǎn)進(jìn)行一些需要的操作
先父組件create->子組件create->子組件mounted->父組件mounted
更新
beforeUpdate->updatedbeforeUpdate 重新渲染和打補(bǔ)丁之前,在這里更改狀態(tài)不會觸發(fā)重新渲染
updated 由于數(shù)據(jù)更改導(dǎo)致的重新渲染和打補(bǔ)丁觸發(fā)
先父組件beforeUpdate-->子組件beforeUpdate->updated->父組件->updated
銷毀
beforeDestroy->DestroyedbeforeDestroy 實(shí)例銷毀之前,里面可以用this
Destroyed 實(shí)例銷毀之后,所以東西解綁,移除所以監(jiān)聽,銷毀所以子實(shí)例,在服務(wù)端渲染不會被調(diào)用
先父組件beforeDestroy-->子組件beforeDestroy->Destroyed->父組件->Destroyed
-
高級特性
- <font color="red">可以不深入,但必須知道</font>
- <font color="red">熟練基本用法,了解使用場景</font>
- <font color="red">最好能和自己的項(xiàng)目經(jīng)驗(yàn)結(jié)合</font>
-
自定義v-model
v-model會默認(rèn)利用名為value的prop和名為input的事件,model會避免單選,復(fù)選將value特性用于不同目的的沖突
v-model等于
<input type="text" :value="val" @input="val=$event.target.value">
demo:
//父組件 <CustomVModel v-model="name"/> <script> import CustomVModel from './CustomVModel' export default { components: { CustomVModel }, data() { return { name: '' } } } </script> // 子組件內(nèi) <template> <!-- 1. input使用了 :value 而不是 v-model 2. change 和 model.even 要對應(yīng) 3. text 屬性要對應(yīng) model.prop 和 props.text --> <input type="text" :value="text" @input="$emit('change', $event.target.value)" /> </template> <script> export default { // 改變默認(rèn)v-model的綁定屬性和拋出事件 model: { prop: 'text' // 對應(yīng)props text, event: 'change' }, props: { text: String, default() { return '' } } } </script> -
$nextTick、$refs
$nextTick
Vue是異步渲染,$nextTick會在DOM渲染之后被觸發(fā)
頁面渲染會將 data 的修改做整合,多次 data 修改只會渲染一次
$refs 在節(jié)點(diǎn)內(nèi)寫ref="dom" 使用this.$refs.dom拿到節(jié)點(diǎn)的dom元素
-
slot
基本使用
父組件在子組件內(nèi)插入節(jié)點(diǎn)內(nèi)容
// 父組件 <SlotDemo> {{user.name}} </SlotDemo> // 子組件 SlotDemo <div> <slot>默認(rèn)顯示</slot> </div>
作用域插槽
父組件在子組件內(nèi)插入節(jié)點(diǎn)內(nèi)容,使用子組件的數(shù)據(jù)
// 父組件 <ScopedSlotDemo> <template v-slot="slotProps"> {{slotProps.slotData.name}} </template> </ScopedSlotDemo> // 子組件 ScopedSlotDemo <div> <slot :slotData="user"></slot> </div>
具名插槽
用于定義多個(gè)插槽
// 父組件 <NameSlot> <template v-slot:header> <h1>插入 header slot中</h1> </template> <p>插入 main slot中,即未命名的 slot</p> <template v-slot:footer> <p>插入 footer slot中</p> </template> </NameSlot> // 子組件 NameSlot <div class="container"> <header> <slot name="header"></slot> </header> <main> <slot></slot> </main> <footer> <slot name="footer"></slot> </footer> </div> -
動(dòng)態(tài)、異步組件
動(dòng)態(tài)組件
用法 :is='component-name'
需要根據(jù)數(shù)據(jù),動(dòng)態(tài)渲染的場景,即組局類型不確定,例如 信息流
<div v-for="item in components" v-key="id"> <component :is="item.name" /> </div> <script> import TextInfoComponent from './TextInfoComponent' import ImageInfoComponent from './TextInfoComponent' export default { components: { TextInfoComponent, ImageInfoComponent }, data() { return { components: [{ id: 1, name: 'TextInfoComponent', },{ id: 2, name: 'ImageInfoComponent', }] } } } </script>
異步組件
import() 函數(shù)
按需加載, 異步加載大組件
export default { conponents: { component: () => import('./component') } } -
keep-alive
緩存組件,頻繁切換,不需要重復(fù)渲染 例如 tab切換
<keep-alive> <KeepAliveStage></KeepAliveStage> </keep-alive> <script> import KeepAliveStage from './KeepAliveStage' export default { conponents: { KeepAliveStage } } </script> -
mixin
多組件有相同的邏輯,抽離出來,和主組件混合合并代碼
會出現(xiàn)問題
- 變量來源不明確,不利于閱讀
- 多mixin會造成命名沖突
- mixin和組件可能出現(xiàn)多對多的關(guān)系,復(fù)雜度較高
Vue 3 提出的Composition API 旨在解決這些問題
// 定義 ./myMixin.js export default { data() { return {} }, mounted() {}, methots: {} } // 使用 import myMixin from './myMixin' export default { mixins: [myMixin] // 可以多個(gè),自動(dòng)合并 }
-
Vuex 使用
可能會考察 state 的數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)
vuex.png
+ 基本概念
1. state // 單一狀態(tài)樹
2. getters // 獲取屬性,計(jì)算屬性啥的
3. actions // 類似控制器,commit 多個(gè) mutations,這里可以異步操作,其他的不行
4. mutations // 更改狀態(tài),必須是同步函數(shù)
5. module // 模塊化Store
6. plugins //插件,相當(dāng)mutation的攔截器,提供store.subscribe((mutation, state) => {})
--------------
+ Vue組件內(nèi)
1. dispatch // 用來觸發(fā) actions
2. commit // 用來觸發(fā) mutations
3. mapState // 映射 state 的函數(shù),computed 中 ...mapState()
4. mapGetters // 映射 getters 的函數(shù),computed 中 ...mapState()
5. mapActions // 映射 actions 的函數(shù),methods 中 ...mapActions()
6. mapMutations // 映射 mutations 的函數(shù),methods 中 ...mapMutations()
-
Vue-router 使用
路由模式(hash,H5 history),后者需要server支持
mode:‘history’
路由配置(動(dòng)態(tài)路由,懶加載)
:id那種,在$route.params.id取到
-
Vue 原理
-
如何理解MVVM
mvvm.pngModel-View-ViewModel 數(shù)據(jù)模型-視圖-視圖數(shù)據(jù)
數(shù)據(jù)驅(qū)動(dòng)視圖
View和Model沒有直接關(guān)聯(lián),ViewMode是給他們提供雙向數(shù)據(jù)綁定的聯(lián)系,優(yōu)點(diǎn)是讓開發(fā)者只需關(guān)注業(yè)務(wù),不需要手動(dòng)操作DOM,也不需要關(guān)注數(shù)據(jù)狀態(tài)同步的問題
-
監(jiān)聽data變化的核心API是什么,怎么深度監(jiān)聽-遞歸
Vue 2 是通過 Object.defineProperty 的 getter 和 setter,并結(jié)合觀察者模式實(shí)現(xiàn)數(shù)據(jù)綁定的
能監(jiān)聽屬性的get set方法
缺點(diǎn)
用于深度監(jiān)聽要遞歸到底,一次性計(jì)算量大
無法監(jiān)聽新增屬性/刪除屬性
無法原生監(jiān)聽數(shù)組,需要特殊處理
Vue 3 是通過 es6的 proxy
優(yōu)點(diǎn)是之前操作的是對象的屬性,現(xiàn)在是操作對象,對js引擎比較友好
缺點(diǎn)是兼容不好,不能用polyfill,不支持低版本瀏覽器
監(jiān)聽數(shù)組-重新定義數(shù)組原型鏈
const oldArrayProperty = Array.prototype // 創(chuàng)建新對象,原型指向oldArrayProperty,在擴(kuò)展新的方法不會影響原型 const arrProto = Object.create(oldArrayProperty) ['push', 'pop', 'shift', 'unshift', 'splice'].forEach(methodName => { arrProto[methodName] = function() { updateView() // 更新視圖 oldArrayProperty[methodName].call(this, ...arguments) } }) -
虛擬DOM
vdom (Virtual DOM) 是實(shí)現(xiàn)vue的重要基石
用JS模擬DOM結(jié)構(gòu),計(jì)算出最小的變更,操作DOM
數(shù)據(jù)驅(qū)動(dòng)視圖,控制DOM操作
-
diff算法
diff算法是vdom中的核心,最關(guān)鍵的部分
vue2 參考snabbdom,雙端比較
diff01.png核心思路
patch新舊vnode的children
新的沒有不管舊的有沒有,就移除children
新舊都有,就去對比新舊vnode的children
新有舊沒有,就添加children
對比新舊vnode的children,先用四個(gè)指針指向新舊nodeChildren的頭尾
然后循環(huán)指針到中間,循環(huán)內(nèi)進(jìn)行對比key和sel是否相等
- 舊children的開始 和 新children的開始 對比
- 舊children的結(jié)束 和 新children的結(jié)束 對比
- 舊children的開始 和 新children的結(jié)束 對比
- 舊children的結(jié)束 和 新children的開始 對比
- 以上有相同的,就執(zhí)行處理新舊節(jié)點(diǎn)的children,并對應(yīng)移動(dòng)指針
- 以上都沒找到相同的,則去用新的key看看舊的里面有沒有,如果沒有則插入,然后移動(dòng)指針,如果有再判斷sel是否相同,不相同就插入,然后移動(dòng)指針,相同就執(zhí)行處理新舊節(jié)點(diǎn)的children,去掉舊節(jié)點(diǎn),插入新節(jié)點(diǎn),然后移動(dòng)指針
// children 和 text 是不會共存的,要么是節(jié)點(diǎn)要么是文本 // elm 對應(yīng)的dom元素 // 所有元素都可以有key Vnode = {sel, data, children, text, elm, key} //先創(chuàng)建Vnode h() => Vnode patch(oldVnode, newVnode) => { if 第一個(gè)參數(shù)不是Vnode 創(chuàng)建一個(gè)空的Vnode,關(guān)聯(lián)到這個(gè)elm元素 if 判斷Vnode是否相同,則去對比(兩個(gè)Vnode的key 和 sel 都相等) Vnode對比: patchVnode() else 不同的Vnode直接刪掉重建 } patchVnode(oldVnode, newVnode) => { 執(zhí)行 prepatch hook 設(shè)置 vnode.elm,把新的 elm 賦值成舊的 elm, 讓新的知道更新到了哪個(gè) elm 得到 oldChildren 和 newChildren if 判斷newVnode 有沒有 children, newVnode.text == undefined (vnode.children 一般有值) if 新舊都有 children 更新children: updateChildren() else if 新 children 有,舊 children 無 (舊 text 有) if 如果就的 text 有值,則清空 text 添加 children else if 新 children 無,舊 children 有 移除 children else 舊 text 有 清空 text 清空 text else vnode.children 沒有值,則刪除舊的 children 并設(shè)置清空 text } // 核心方法 updateChildren(elm, oldChildren, newChildren) => { // 用于循環(huán)從四周到中間 定義指針 oldStartIndex, oldEndIndex, newStartIndex, oldStartIndex while(指針到中間停止) { if 判斷元素是否是空,操作指針移動(dòng) else if oldStart == newStart 開始和開始,判斷是否相同(key 和 sel 都相等) patchVnode(), 操作指針移動(dòng) else if oldEnd == newEnd 結(jié)束和結(jié)束,判斷是否相同(key 和 sel 都相等) patchVnode(), 操作指針移動(dòng) else if oldStart == newEnd 開始和結(jié)束,判斷是否相同(key 和 sel 都相等) patchVnode(), 操作指針移動(dòng) else if oldEnd == newStart 結(jié)束和開始,判斷是否相同(key 和 sel 都相等) patchVnode(), 操作指針移動(dòng) else 以上四個(gè)都未命中 // 用新節(jié)點(diǎn) key,判斷能否對應(yīng) oldChildren 中某個(gè)節(jié)點(diǎn)的 key 在oldChildren中,用新節(jié)點(diǎn)的key去拿節(jié)點(diǎn) if 沒拿到?jīng)]對應(yīng)上,則 插入新節(jié)點(diǎn), 操作指針移動(dòng) else 對應(yīng)上 if sel 是否相等 插入新節(jié)點(diǎn), 操作指針移動(dòng) else key 和 sel 都相等 patchVnode(),去掉舊節(jié)點(diǎn),插入新節(jié)點(diǎn), 操作指針移動(dòng) } }vue3 參考inferno,最長遞增子序列
兩個(gè)理念。第一個(gè)是相同的前置與后置元素的預(yù)處理;第二個(gè)則是最長遞增子序列
從頭對比找到相同的節(jié)點(diǎn)patch,發(fā)現(xiàn)不同則跳出
如果1沒有patch完,則從后往前找相同的節(jié)點(diǎn)patch,發(fā)現(xiàn)不同則跳出
如果新節(jié)點(diǎn)大于與舊節(jié)點(diǎn),對剩余的都創(chuàng)建新的vnode
如果舊節(jié)點(diǎn)大于新節(jié)點(diǎn),對于超出的舊節(jié)點(diǎn)全部卸載
-
如果3,4都沒有,則是對于不確定的元素(沒有patch到相同的vnode)
把沒有比較過的新vnode保存在map里
記錄已經(jīng)patch節(jié)點(diǎn)的熟練patched,沒有經(jīng)過patch的新節(jié)點(diǎn)數(shù)量tuBePatched
建立一個(gè)數(shù)組newIndexToOldIndexMap,每個(gè)元素都記錄舊節(jié)點(diǎn)的索引,這個(gè)數(shù)組的索引就是新節(jié)點(diǎn)的索引
-
遍歷舊節(jié)點(diǎn)
- 如果toBePatched為0,那么統(tǒng)一卸載舊節(jié)點(diǎn)
- 如果舊節(jié)點(diǎn)key存在,通過key找到對應(yīng)新節(jié)點(diǎn)的index
- 如果舊節(jié)點(diǎn)key不存在,遍歷剩下的所有新節(jié)點(diǎn),試圖找到新節(jié)點(diǎn)對應(yīng)的index
- 如果沒有找到對應(yīng)的新節(jié)點(diǎn)就卸載舊節(jié)點(diǎn)
- 如果找到對應(yīng)的新節(jié)點(diǎn),把舊節(jié)點(diǎn)的索引記錄在新節(jié)點(diǎn)的數(shù)組中,如果節(jié)點(diǎn)發(fā)生移動(dòng)就記錄已經(jīng)移動(dòng)了,最后patch新節(jié)點(diǎn)
如果發(fā)生移動(dòng),根據(jù)newIndexToOldIndexMap找到最長穩(wěn)定序列,
如果證明不存在舊節(jié)點(diǎn)就創(chuàng)建新節(jié)點(diǎn),對于發(fā)生移動(dòng)的節(jié)點(diǎn)進(jìn)行移動(dòng)處理
-
-
模版編譯
模版編譯為 render 函數(shù),執(zhí)行 render 函數(shù)返回 vnode
基于 vnode 再執(zhí)行 patch 和 diff
使用webpack vue-loader
-
JS的 with 語法
改變 {} 內(nèi)自由變量的查找規(guī)則,當(dāng)做 obj 屬性來查找
如果找不到匹配的 obj 屬性,就會報(bào)錯(cuò)
with 要慎用,它打破了作用域規(guī)則,易讀性變差
// with 能改變 {} 內(nèi)自由變量的查找方式,將 {} 內(nèi)自由變量,當(dāng)做 obj 的屬性來查找 const obj = {a:100, b:200} console.log(obj.a) console.log(obj.b) console.log(obj.c) // undefined with(obj) { console.log(a) console.log(b) console.log(c) // 會報(bào)錯(cuò) }
-
組件 渲染/更新 過程

> 初次渲染的過程
>
> > 解析模版為 render 函數(shù)
> >
> > 觸發(fā)響應(yīng)式,監(jiān)聽 data 屬性的 getter setter
> >
> > 執(zhí)行 render 函數(shù),生成 vnode, 執(zhí)行 patch(elm, vnode)
>
> 更新過程
>
> > 修改 data,觸發(fā) setter
> >
> > 重新執(zhí)行 render 函數(shù),生成 newVnode
> >
> > 執(zhí)行 patch(vnode, newVnode)
>
> 異步渲染 $nextTick
>
> > 匯總 data 的修改,一次性更新視圖
> >
> > 減少 DOM 操作次數(shù),提升性能
-
路由原理
稍微復(fù)制的SPA,都需要路由
hash-window.onhashchange
H5 history-history.pushState 和 window.onpopstate
H5 history 需要后端支持
兩者選擇
toB 推薦hash,簡單易用,對 url 規(guī)范不敏感
toC 可以考慮選擇H5 history,但需要服務(wù)端支持
能選擇簡單的就別用復(fù)雜的,要考慮成本和收益
hash 特點(diǎn)
hash 變化會觸發(fā)網(wǎng)頁跳轉(zhuǎn),即瀏覽器的前期、后退
hash 變化不會刷新頁面,SPA必需的特點(diǎn)
hash 永遠(yuǎn)不會提交到server端(前端自生自滅)
H5 history
用 url 規(guī)范的路由,但跳轉(zhuǎn)時(shí)不刷新頁面
history.pushState
window.onpopstate
-
面試題
v-show 和 v-if 的區(qū)別
v-show 通過 css display 控制顯示和隱藏
v-if 是組件真正的渲染和銷毀,而不是顯示和隱藏
頻繁切換顯示狀態(tài)用 v-show,否則用 v-if
為什么 v-for 中用 key
必須用 key,而且不能是 index 和 random
diff 算法中通過 tag 和 key 來判斷,是否是 sameNode
減少渲染次數(shù),提升渲染性能
描述 vue 組件的生命周期
單組件生命周期圖
父子組件生命周期關(guān)系比如 mount 和 update
Vue 組件如何通訊
父子組件 props 和 this.$emit
自定義事件 event.
off event.$emit
vuex
描述組件渲染和更新的過程
渲染圖
雙向數(shù)據(jù)綁定 v-model 的實(shí)現(xiàn)原理
input 元素的 value = this.name
綁定 input 事件 this.name = $event.target.value
data 更新觸發(fā) re-render
對 MVVM 的理解
computed 有何特點(diǎn)
緩存,data 不變不會重新計(jì)算
提高性能
為何組件 data 必須是一個(gè)函數(shù)
js 特性導(dǎo)致的,Object 是引用數(shù)據(jù)類型,會導(dǎo)致同一個(gè)屬性改一個(gè)都變了,是函數(shù)的時(shí)候才能實(shí)例獨(dú)立不相互影響
ajax 應(yīng)該放在哪個(gè)生命周期
mounted
js 是單線程,ajax 是異步獲取數(shù)據(jù)
放在 mounted 之前沒有用,只會讓邏輯更加混亂,除非有特殊需求
如何將組件所有的 props 傳遞給子組件
$props
<Uer v-bind="$props" />
如何自己實(shí)現(xiàn) v-model
多個(gè)組件有相同的邏輯,如何抽離
mixin
mixin 的缺點(diǎn)
何時(shí)要使用異步組件
加載大組件
路由異步加載
何時(shí)需要使用 keep-alive
緩存組件,不需要重復(fù)渲染
多個(gè)靜態(tài) tab 頁的切換
優(yōu)化性能
何時(shí)需要使用beforeDestory
解綁自定義事件 event.$off
清楚定時(shí)器
解綁自定義的 DOM 事件,如 window scroll 等
什么是作用域插槽
把子組件的數(shù)據(jù)傳給父組件顯示
vuex 中 action 和 mutation 有何區(qū)別
action 中處理異步,mutation 不可以
mutation 做原子操作
action 可以整合多個(gè) mutation
vue-router 常用的路由模式
hash 默認(rèn)
H5 history
vue-router 兩種模式是怎么實(shí)現(xiàn)的
hash window.onhashchange
H5 history window.history.pushState window.history.onpopstate
vue-router 兩種模式的區(qū)別
hash有#號,能控制瀏覽器前后跳轉(zhuǎn),不會提交到server端
H5 history 是規(guī)范 url,需要 server 端配合
如何配置 vue-router 異步加載
通過 () => import()
用 vnode 描述一個(gè) DOM 結(jié)構(gòu)
監(jiān)聽 data 變化的核心 API 是什么
Object.defineProperty
有何缺點(diǎn)
深度監(jiān)聽需要遞歸、監(jiān)聽數(shù)組需要特殊處理,無法監(jiān)聽新增和刪除的屬性,使用vue.set vue.delete
Vue3 Proxy 兼容問題,而且不能 polyfill
Vue 如何監(jiān)聽數(shù)組變化
Object.defineProperty 不能監(jiān)聽數(shù)組變化
重新定義原型,重新push pop等方法,實(shí)現(xiàn)監(jiān)聽
Proxy 可以原生支持監(jiān)聽數(shù)組變化
描述響應(yīng)式原理
監(jiān)聽 data 變化
組件渲染和更新的流程
diff 算法的時(shí)間復(fù)雜度
O(n) ,在O(n^3)基礎(chǔ)上做的調(diào)整,只比較同一層級,比較tag不相同直接銷毀重建,通過tag和key判斷是不是同一組件,是就不重復(fù)對比
簡述 diff 算法過程
patch(elem, vnode) 和 patch(vnode, newVnode)
patchVnode 和 addVnodes 和 removeVnodes
updateChildren,通過key判斷是不是同一節(jié)點(diǎn)
vue為何是異步渲染,$nextTick 何用
異步渲染,合并 data 修改,提高性能
$nextTick 在 DOM 更新之后,觸發(fā)回調(diào)
vue 常見性能優(yōu)化
合理使用 v-show v-if
合理使用 computed
v-for 時(shí)加 key,以及避免和 v-if 同時(shí)使用
自定義事件,DOM事件及時(shí)銷毀
合理使用異步組件
合理使用 keep-alive
data 層級不要太深
使用 vue-loader 在開發(fā)環(huán)境做模版編譯(預(yù)編譯)
webpack 層面的優(yōu)化
前端通用的性能優(yōu)化,如圖片懶加載
使用ssr
-
Vue 3
Vue3 比 Vue2 有什么優(yōu)勢
性能更好
體積更小
更好的 ts 支持
更好的代碼組織
更好的邏輯抽離
更多新功能
Vue3 聲明周期
Options API: beforeDestory 改為 beforeUnmount destoryed 改為 unmouted
升級內(nèi)容
全部用 ts 重寫
性能提升,代碼量減少
調(diào)整部分API
持續(xù)更新中...


