Vue面試題
v-html 會有XSS風(fēng)險,會覆蓋子組件
computed 有緩存蚕断,data不變則不會重新計算
watch 默認(rèn)不會深度監(jiān)聽欢伏,要deep:true開啟
watch 監(jiān)聽引用類型入挣,拿不到oldVal,因?yàn)橹羔樝嗤跖。藭r已經(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中及時銷毀監(jiān)聽事件赶站,否則可能造成內(nèi)存泄露
event.$off('onHandle', this.handle)
-
組件生命周期 <font color="red">* 必須背會</font>
掛載
beforeCreate->create->beforeMount->mounted
beforeCreate里沒有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->updated
beforeUpdate 重新渲染和打補(bǔ)丁之前,在這里更改狀態(tài)不會觸發(fā)重新渲染
updated 由于數(shù)據(jù)更改導(dǎo)致的重新渲染和打補(bǔ)丁觸發(fā)
先父組件beforeUpdate-->子組件beforeUpdate->updated->父組件->updated
銷毀
beforeDestroy->Destroyed
beforeDestroy 實(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>
具名插槽
用于定義多個插槽
// 父組件 <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>
-
動態(tài)蹲堂、異步組件
動態(tài)組件
用法 :is='component-name'
需要根據(jù)數(shù)據(jù),動態(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] // 可以多個枕磁,自動合并 }
-
Vuex 使用
可能會考察 state 的數(shù)據(jù)結(jié)構(gòu)設(shè)計
vuex.png
+ 基本概念
1. state // 單一狀態(tài)樹
2. getters // 獲取屬性茂翔,計算屬性啥的
3. actions // 類似控制器蝙场,commit 多個 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’
路由配置(動態(tài)路由哭靖,懶加載)
:id那種,在$route.params.id取到
-
Vue 原理
-
如何理解MVVM
mvvm.pngModel-View-ViewModel 數(shù)據(jù)模型-視圖-視圖數(shù)據(jù)
數(shù)據(jù)驅(qū)動視圖
View和Model沒有直接關(guān)聯(lián)侈离,ViewMode是給他們提供雙向數(shù)據(jù)綁定的聯(lián)系试幽,優(yōu)點(diǎn)是讓開發(fā)者只需關(guān)注業(yè)務(wù),不需要手動操作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)聽要遞歸到底,一次性計算量大
無法監(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),計算出最小的變更橘忱,操作DOM
數(shù)據(jù)驅(qū)動視圖,控制DOM操作
-
diff算法
diff算法是vdom中的核心卸奉,最關(guān)鍵的部分
vue2 參考snabbdom钝诚,雙端比較
diff01.png核心思路
patch新舊vnode的children
新的沒有不管舊的有沒有,就移除children
新舊都有榄棵,就去對比新舊vnode的children
新有舊沒有凝颇,就添加children
對比新舊vnode的children,先用四個指針指向新舊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)移動指針
- 以上都沒找到相同的瘪弓,則去用新的key看看舊的里面有沒有垫蛆,如果沒有則插入,然后移動指針腺怯,如果有再判斷sel是否相同袱饭,不相同就插入,然后移動指針呛占,相同就執(zhí)行處理新舊節(jié)點(diǎn)的children虑乖,去掉舊節(jié)點(diǎn),插入新節(jié)點(diǎn)晾虑,然后移動指針
// 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 第一個參數(shù)不是Vnode 創(chuàng)建一個空的Vnode,關(guān)聯(lián)到這個elm元素 if 判斷Vnode是否相同,則去對比(兩個Vnode的key 和 sel 都相等) Vnode對比: patchVnode() else 不同的Vnode直接刪掉重建 } patchVnode(oldVnode, newVnode) => { 執(zhí)行 prepatch hook 設(shè)置 vnode.elm帜篇,把新的 elm 賦值成舊的 elm, 讓新的知道更新到了哪個 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 判斷元素是否是空逃沿,操作指針移動 else if oldStart == newStart 開始和開始婴渡,判斷是否相同(key 和 sel 都相等) patchVnode(), 操作指針移動 else if oldEnd == newEnd 結(jié)束和結(jié)束,判斷是否相同(key 和 sel 都相等) patchVnode(), 操作指針移動 else if oldStart == newEnd 開始和結(jié)束凯亮,判斷是否相同(key 和 sel 都相等) patchVnode(), 操作指針移動 else if oldEnd == newStart 結(jié)束和開始边臼,判斷是否相同(key 和 sel 都相等) patchVnode(), 操作指針移動 else 以上四個都未命中 // 用新節(jié)點(diǎn) key,判斷能否對應(yīng) oldChildren 中某個節(jié)點(diǎn)的 key 在oldChildren中假消,用新節(jié)點(diǎn)的key去拿節(jié)點(diǎn) if 沒拿到?jīng)]對應(yīng)上柠并,則 插入新節(jié)點(diǎn), 操作指針移動 else 對應(yīng)上 if sel 是否相等 插入新節(jié)點(diǎn), 操作指針移動 else key 和 sel 都相等 patchVnode(),去掉舊節(jié)點(diǎn),插入新節(jié)點(diǎn), 操作指針移動 } }
vue3 參考inferno臼予,最長遞增子序列
兩個理念鸣戴。第一個是相同的前置與后置元素的預(yù)處理;第二個則是最長遞增子序列
從頭對比找到相同的節(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
建立一個數(shù)組newIndexToOldIndexMap疏之,每個元素都記錄舊節(jié)點(diǎn)的索引,這個數(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ā)生移動就記錄已經(jīng)移動了沃呢,最后patch新節(jié)點(diǎn)
如果發(fā)生移動年栓,根據(jù)newIndexToOldIndexMap找到最長穩(wěn)定序列,
如果證明不存在舊節(jié)點(diǎn)就創(chuàng)建新節(jié)點(diǎn)薄霜,對于發(fā)生移動的節(jié)點(diǎn)進(jìn)行移動處理
-
-
模版編譯
模版編譯為 render 函數(shù)某抓,執(zhí)行 render 函數(shù)返回 vnode
基于 vnode 再執(zhí)行 patch 和 diff
使用webpack vue-loader
-
JS的 with 語法
改變 {} 內(nèi)自由變量的查找規(guī)則,當(dāng)做 obj 屬性來查找
如果找不到匹配的 obj 屬性惰瓜,就會報錯
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) // 會報錯 }
-
組件 渲染/更新 過程
> 初次渲染的過程
>
> > 解析模版為 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)時不刷新頁面
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 不變不會重新計算
提高性能
為何組件 data 必須是一個函數(shù)
js 特性導(dǎo)致的,Object 是引用數(shù)據(jù)類型黄虱,會導(dǎo)致同一個屬性改一個都變了稚矿,是函數(shù)的時候才能實(shí)例獨(dú)立不相互影響
ajax 應(yīng)該放在哪個生命周期
mounted
js 是單線程,ajax 是異步獲取數(shù)據(jù)
放在 mounted 之前沒有用捻浦,只會讓邏輯更加混亂晤揣,除非有特殊需求
如何將組件所有的 props 傳遞給子組件
$props
<Uer v-bind="$props" />
如何自己實(shí)現(xiàn) v-model
多個組件有相同的邏輯,如何抽離
mixin
mixin 的缺點(diǎn)
何時要使用異步組件
加載大組件
路由異步加載
何時需要使用 keep-alive
緩存組件朱灿,不需要重復(fù)渲染
多個靜態(tài) tab 頁的切換
優(yōu)化性能
何時需要使用beforeDestory
解綁自定義事件 event.$off
清楚定時器
解綁自定義的 DOM 事件昧识,如 window scroll 等
什么是作用域插槽
把子組件的數(shù)據(jù)傳給父組件顯示
vuex 中 action 和 mutation 有何區(qū)別
action 中處理異步,mutation 不可以
mutation 做原子操作
action 可以整合多個 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 描述一個 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 算法的時間復(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 時加 key墓猎,以及避免和 v-if 同時使用
自定義事件捆昏,DOM事件及時銷毀
合理使用異步組件
合理使用 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ù)更新中...