vue2 vs vue3
對比 | vue2 | vue3 |
---|---|---|
腳手架 | 命令式 | 可視化創(chuàng)建腳?架 |
組件通信 | 見下文 | 見下文 |
數(shù)據(jù)監(jiān)聽 | watch,computed | watch,watchEffect,computed |
雙向綁定 | Object.defineProperty | ProxyAPI |
?命周期 | 見下文 | 見下文 |
api | 選項式 | 組合式 |
雙向綁定更新
vue2 的雙向數(shù)據(jù)綁定是利?ES5 的?個 API ,Object.defineProperty()
對數(shù)據(jù)進(jìn)?劫持 結(jié)合 發(fā)布訂閱模式的?式來實現(xiàn)的。
vue3 中使?了 ES6 的 ProxyAPI
對數(shù)據(jù)代理,通過 reactive()
函數(shù)給每?個對象都包?層 Proxy,通過 Proxy 監(jiān)聽屬性的變化,從? 實現(xiàn)對數(shù)據(jù)的監(jiān)控。
這?是相?于vue2版本,使?proxy的優(yōu)勢如下
1.
defineProperty
只能監(jiān)聽某個屬性崎淳,不能對全對象監(jiān)聽 可以省去for in、閉包等內(nèi)容來提升效率(直接綁定整個對象即可)2.可以監(jiān)聽數(shù)組愕把,不?再去單獨的對數(shù)組做特異性操作,通過Proxy可以直接攔截所有對象類型數(shù)據(jù)的操作拣凹,完美?持對數(shù)組的監(jiān)聽森爽。
實例化
Vue2.x中new出的實例對象,所有的東西都在這個vue對象上嚣镜,這樣其實?論你?到還是沒?到爬迟,都會跑?遍,這樣不僅提?了性能消耗祈惶,也?疑增加了?戶加載時間雕旨。
?vue3.0中可以?ES module imports
按需引?,如:keep-alive內(nèi)置組件捧请、v-model指令凡涩,等等,不僅我們開發(fā)起來更加的便捷疹蛉,減少 了內(nèi)存消耗活箕,也同時減少了?戶加載時間,優(yōu)化?戶體驗可款。
生命周期
引用掘金圖片如下:
獲取props
vue2在script代碼塊可以直接獲取props育韩,vue3通過setup指令傳遞
vue2:console.log('props',this.xxx)
vue3:setup(props,context){ console.log('props',props) }
數(shù)據(jù)和方法的定義
Vue2使?的是選項類型API(Options API),Vue3使?的是合成型API(Composition API)
Vue2:
data() { return {}; }, methods:{ }
Vue3:
數(shù)據(jù)和?法都定義在setup中闺鲸,并統(tǒng)?進(jìn)?return{}
給父組件傳值emit
vue2:this.$emit()
vue3:setup(props,context){context.emit()}
watchEffect
Vue3中除了watch筋讨,還引入了副作用監(jiān)聽函數(shù)watchEffect,用過之后我發(fā)現(xiàn)它和React中的useEffect很像摸恍,只不過watchEffect不需要傳入依賴項悉罕。
那么什么是watchEffect呢?
watchEffect它會立即執(zhí)行傳入的一個函數(shù)立镶,同時響應(yīng)式追蹤其依賴壁袄,并在其依賴變更時重新運行該函數(shù)。
computed和watch所依賴的數(shù)據(jù)必須是響應(yīng)式的媚媒。
Vue3引入了watchEffect
嗜逻,watchEffect 相當(dāng)于將 watch 的依賴源和回調(diào)函數(shù)合并,當(dāng)任何你有用到的響應(yīng)式依賴更新時缭召,該回調(diào)函數(shù)便會重新執(zhí)行栈顷。
不同于 watch的是watchEffect的回調(diào)函數(shù)會被立即執(zhí)行,即({ immediate: true })
嵌巷。
組件通信
注意
props中數(shù)據(jù)流是單項的萄凤,即子組件不可改變父組件傳來的值
在組合式API中,如果想在子組件中用其它變量接收props的值時需要使用toRef將props中的屬性轉(zhuǎn)為響應(yīng)式晴竞。
attrs和listeners
子組件使用$attrs可以獲得父組件除了props傳遞的屬性和特性綁定屬性 (class和 style)之外的所有屬性。
子組件使用$listeners可以獲得父組件(不含.native修飾器的)所有v-on事件監(jiān)聽器狠半,在Vue3中已經(jīng)不再使用噩死;
但是Vue3中的attrs不僅可以獲得父組件傳來的屬性也可以獲得父組件v-on事件監(jiān)聽器
路由
vue3和vue2路由常用功能只是寫法上有些區(qū)別:
vue3的beforeRouteEnter
作為路由守衛(wèi)的示例是因為它在setup
語法糖中是無法使用的颤难;
大家都知道setup
中組件實例已經(jīng)創(chuàng)建,是能夠獲取到組件實例的已维。
而beforeRouteEnter
是再進(jìn)入路由前觸發(fā)的行嗤,此時組件還未創(chuàng)建,所以是無法用在setup
中的垛耳;如果想在setup語法糖中使用則需要再寫一個script
如下:
<script>
export default {
beforeRouteEnter(to, from, next) {
// 在渲染該組件的對應(yīng)路由被 confirm 前調(diào)用
next()
},
};
</script>
vue3路由寫法:
<script>
import { defineComponent } from 'vue'
import { useRoute, useRouter } from 'vue-router'
export default defineComponent({
beforeRouteEnter (to, from, next) {
// 在渲染該組件的對應(yīng)路由被 confirm 前調(diào)用
next()
},
beforeRouteLeave ((to, from, next)=>{//離開當(dāng)前的組件栅屏,觸發(fā)
next()
}),
beforeRouteLeave((to, from, next)=>{//離開當(dāng)前的組件,觸發(fā)
next()
}),
setup() {
const router = useRouter()
const route = useRoute()
const toPage = () => {
router.push(xxx)
}
//獲取params 注意是route
route.params
//獲取query
route.query
return {
toPage
}
},
});
</script>
vue2寫法:
<script>
export default {
beforeRouteEnter (to, from, next) {
// 在渲染該組件的對應(yīng)路由被 confirm 前調(diào)用
next()
},
beforeRouteEnter (to, from, next) {
// 在渲染該組件的對應(yīng)路由被 confirm 前調(diào)用
next()
},
beforeRouteLeave ((to, from, next)=>{//離開當(dāng)前的組件堂鲜,觸發(fā)
next()
}),
beforeRouteLeave((to, from, next)=>{//離開當(dāng)前的組件栈雳,觸發(fā)
next()
}),
methods:{
toPage(){
//路由跳轉(zhuǎn)
this.$router.push(xxx)
}
},
created(){
//獲取params
this.$route.params
//獲取query
this.$route.query
}
}
</script>