今天看了vue2升遷vue3相關知識倾鲫,這里列舉一部分比較常用的不同之處
v-for數(shù)組中的ref屬性的使用(這個屬性是非兼容的)
- vue2: 使用this.$refs[屬性名]的方式獲取到一個元素數(shù)組
<div v-for="(item,index) in list" ref="setItemRef" :key="index">
{{item.name}}
</div>
<button @click="getRef">獲取ref</button>
export default {
data() {
return {
list: [
{ name: '小錢1'},
{ name: '小花'}
]
};
},
methods: {
getRef() {
console.log(this.$refs.setItemRef) // (2) [div, div]
}
}
}
- vue3:
不再通過this.$refs方式獲取,而是通過一個同名函數(shù)去獲取對應元素扩借,這個函數(shù),你只需要定義保檐,vue3會自調用它麻蹋,不需要手動調用韩肝。
此外,可以使用一個數(shù)組對象來保存獲取到的元素集合祸轮,它返回是一個類數(shù)組的Proxy對象兽埃,這樣還可以起到防止用戶直接篡改數(shù)組來改變元素
<div v-for="(item,index) in list" ref="setItemRef" :key="index">
{{item.name}}
</div>
<button @click="getRef">獲取ref</button>
export default {
data() {
return {
itemRefs: []
}
},
methods: {
setItemRef(el) {
this.itemRefs.push(el)
},
getRef() {
console.log(this.itemRefs) // 類數(shù)組的Proxy對象适袜,[div, div], itemRefs可以定義為數(shù)組柄错,也可以定義為對象
}
}
}
$children
vue2中可以通過this.$children獲取當前組件的所有子組件對象
vue3中已刪除此API,可以使用this.$ref[子組件的ref名稱]來替代獲取
插槽的改變
vue2.5以前苦酱,插槽的使用方式是:
<!-- slot-comp -->
<template>
<div>
<slot name="hasData" :data="data" age="18"></slot>
</div>
</template>
<!-- parent -->
<slot-comp>
<!-- 傳統(tǒng)寫法:帶數(shù)據(jù)的插槽, slotData是所有寫在slot插槽上的屬性集合 -->
<template slot="hasData" slot-scope="slotData">
<!-- { "data": [ 1, 2, 3 ], "age": "18" } -->
{{slotData}}
</template>
</slot-comp>
vue2.6時售貌,已改為v-slot的方式,文檔中雖然說廢除之前的傳統(tǒng)寫法疫萤,但在實際中颂跨,還是向下兼容的,所以在vue2中使用哪種方式目前都是可以的
<!-- slot-comp -->
<template>
<div>
<!-- 帶數(shù)據(jù)的插槽:作用域插槽 -->
<slot name="hasData" :data="data" age="18"></slot>
</div>
</template>
<!-- parent -->
<slot-comp>
<!-- 縮寫寫法: <template #:hasData="data"> -->
<template v-slot:hasData="data">
<!-- { "data": [ 1, 2, 3 ], "age": "18" } -->
{{data}}
</template>
</slot-comp>
在vue3時扯饶,不再向下兼容恒削,只支持v-slot的寫法(也可以縮寫為#):
在element-ui中就使用的是vue2.5以前的傳統(tǒng)插槽方式;
element-plus就改為了vue3支持的#(v-slot)寫法帝际,所以說element-ui不支持vue3也有這個原因
響應式
- vue2的響應式是使用defineProperty來對數(shù)據(jù)劫持的蔓同,它有大的局限性:
- 需要遍歷data中的對象,來綁定劫持數(shù)據(jù)蹲诀,如果對象嵌套對象斑粱,那么需要遞歸遍歷調用defineProperty來實現(xiàn)響應式,當對象嵌套很深時脯爪,對性能消耗會很大
- 不支持數(shù)組中對象的響應式则北,包括現(xiàn)在還有這個bug矿微,通過數(shù)組下標改變一下對象,是無法做到響應式的尚揣;尤大大自己也回復說涌矢,是因為性能問題,所以才沒實現(xiàn)快骗,這還是跟第1個遞歸遍歷有關娜庇,當嵌套過多,性能會比較差
export default {
data() {
return {
list: [
{ name: '小錢1'},
{ name: '小花'}
]
};
},
methods: {
change() {
this.list[0] = { name: '小飛' } // 在頁面中是不響應的
}
}
}
- 不支持對象的增加或刪除響應式
- vue3使用Proxy方篮,它自然地監(jiān)聽對象下的所有屬性名秀,解決了vue2響應式的問題,因為不需要遞歸去遍歷藕溅,所以它本身的性能就很好
composition API
- vue2支持的是options API:
當我們要修改一個變量時匕得,它如果涉及到很多地方,比如data中定義巾表,在某個methods中修改汁掠,然后可能watch時也會修改,業(yè)務代碼是離散的集币;
當文件很大時考阱,每次修改相關業(yè)務,我們都要滑動鼠標去查找對應的好些地方才能修改完惠猿,一個是麻煩羔砾,二個是很容易漏改某處,開發(fā)體驗不是很好偶妖。
- vue3支持composition API姜凄,它將業(yè)務有聯(lián)系的代碼統(tǒng)一放到setup函數(shù)中,當修改時趾访,我們可以集中修改這塊業(yè)務代碼
- 開發(fā)體驗好态秧,修改起來集中且容易查找
- 因為業(yè)務代碼集中,更靈活的邏輯組織扼鞋,方便拆分和抽象組件申鱼,更利于組件復用
- 沒有this,再也不用糾結this上到底有什么
- 更友好的tree-shaking支持
- 更大的代碼壓縮空間
- 更好的類型推導能力(typescript)云头,因為setup本質是一個函數(shù)捐友,它的輸入和輸出是固定的,所以能更好推導類型
composition API語法
compostion API都是寫在一個setup的方法中:
- 一般使用ref來定義基礎類型數(shù)據(jù)
- 使用reactive來定義數(shù)組或對象
- 跟上面變量相關的方法也都定義在setup方法中溃槐,定義寫法和普通的方法一樣
- 無論定義的是什么匣砖,都要return出去才生效
- setup的生命周期:
- setup是在beforeCreate生命周期前執(zhí)行:setup -> beforeCreate -> created
- setup中也有自己的生命周期函數(shù),即vue的生命周期(除了beforeCreate和created兩個)前加'on',就是它的生命周期倒數(shù)猴鲫,比如onMounted对人,但是所有生命周期都必須寫在return前面
- 要使用的生命周期必須從vue導入(PS:之前的ref、reactive定義變量的方法也要導入)
composition API的實現(xiàn):
// 導入ref, reactive, onMounted
import { reactive, computed, onMounted } from 'vue'
export default {
setup() {
console.log('setup')
// 基礎類型的定義
const x = Ref(x)
// 數(shù)組或對象定義
const obj = reactive({
name: 'xx',
list: ['xxx']
})
function changeX() {
x.value = 22
obj.name = 'xxx'
}
// setup中的生命周期
onMounted() {
obj.name = 'xx2'
}
// 無論是什么拂共,都必須return出去才生效
return {
x,
obj,
changeX
}
},
beforeCreate() {
console.log('beforeCreate')
},
created() {
console.log('created')
}
}
項目升級評估(是否要從vue2升級到vue3):
項目量級及業(yè)務需求
如果項目非常大(比如沉淀好幾年的老項目牺弄,基數(shù)非常大),且業(yè)務非常復雜(需求不熟悉的話根本理不清宜狐,改一處n個bug那種)势告,建議不要升!
業(yè)務對技術升級是不是有要求抚恒,有要求才升級培慌,不要因為想使用新技術而升級,要從業(yè)務角度出發(fā)團隊能力
如果團隊能力水平參差不齊的話柑爸,有的人對vue3很了解,有的人壓根不會盒音,那很有可能因為團隊能力不齊導致升級失敗不兼容代碼評估
一定一定要參考官網升遷文檔:https://vue3js.cn/docs/zh/guide/migration/functional-components.html#_2-x-%E8%AF%AD%E6%B3%95
明確升遷的變動范圍和成本第3方擴展插件評估
評估下原項目使用的插件表鳍,在vue3中是否已經有了對應的升遷擴展,目前vuex,vue-router,element-plus都支持vue3的版本祥诽,但還要考慮項目中其它插件綜合成本評估
從人力譬圣、時間、花費等方面去綜合考慮
詳細的還是推薦大家仔細閱讀下官網:
https://v3.vuejs.org/guide/introduction.html#conditionals-and-loops
https://vue3js.cn/docs/zh/guide/migration/functional-components.html#_2-x-%E8%AF%AD%E6%B3%95