vue2和vue3雙向數(shù)據(jù)綁定原理發(fā)生了改變
vue2 的雙向數(shù)據(jù)綁定是利用ES5 的一個 API Object. defineProperty()對數(shù)據(jù)進(jìn)行劫持 結(jié)合 發(fā)布訂閱模式的方式來實現(xiàn)的。
// 數(shù)據(jù)劫持:當(dāng)訪問或者設(shè)置 vm 中的成員的時候,做一些干預(yù)操作
Object.defineProperty(vm, 'msg', {
// 可枚舉(可遍歷)
enumerable: true,
// 可配置(可以使用 delete 刪除,可以通過 defineProperty 重新定義)
configurable: true,
// 當(dāng)獲取值的時候執(zhí)行
get () {
console.log('get: ', data.msg)
return data.msg
},
// 當(dāng)設(shè)置值的時候執(zhí)行
set (newValue) {
console.log('set: ', newValue)
if (newValue === data.msg) {
return
}
data.msg = newValue
// 數(shù)據(jù)更改,更新 DOM 的值
document.querySelector('#app').textContent = data.msg
}
})
vue3 中使用了 es6 的 ProxyAPI 對數(shù)據(jù)代理。
// 模擬 Vue 實例
let vm = new Proxy(data, {
// 執(zhí)行代理行為的函數(shù)
// 當(dāng)訪問 vm 的成員會執(zhí)行
get (target, key) {
console.log('get, key: ', key, target[key])
return target[key]
},
// 當(dāng)設(shè)置 vm 的成員會執(zhí)行
set (target, key, newValue) {
console.log('set, key: ', key, newValue)
if (target[key] === newValue) {
return
}
target[key] = newValue
document.querySelector('#app').textContent = target[key]
}
})
相比于vue2.x,使用proxy的優(yōu)勢如下
defineProperty只能監(jiān)聽某個屬性,不能對全對象監(jiān)聽
可以省去for in、閉包等內(nèi)容來提升效率(直接綁定整個對象即可)
可以監(jiān)聽數(shù)組,不用再去單獨的對數(shù)組做特異性操作 vue3.x可以檢測到數(shù)組內(nèi)部數(shù)據(jù)的變化
vue2和vue3定義數(shù)據(jù)變量和方法的改變
在vue2中定義數(shù)據(jù)變量是data(){},創(chuàng)建的方法要在methods:{}中。
而在vue3中直接在setup(){}中,在這里面定義的變量和方法因為最終要在模板中使用,所以最后都得 return。setup里面沒有this。
如:
<script lang="ts">
import { defineComponent, ref } from 'vue';
export default defineComponent({
name: 'App',
setup() {
//使用ref,說明這個數(shù)組就是全局在面板中可以使用了
const girls = ref(['data1','data2','data3'])
const selectGirl = ref('2')
//設(shè)置一個函數(shù)
const selectGirlFun = (index: number) => {
//改變selectGirl的值要加value
//要得到值要加value ,這些都因為使用了ref函數(shù)
selectGirl.value = girls.value[index]
}
//在標(biāo)簽中使用的變量要使用return
//為什么要使用return,因為有的不需要在標(biāo)簽中使用的就不用return
return{
girls,
selectGirl,
selectGirlFun
}
},
});
</script>
默認(rèn)進(jìn)行懶觀察(lazy observation)。
在 2.x 版本里,不管數(shù)據(jù)多大,都會在一開始就為其創(chuàng)建觀察者。當(dāng)數(shù)據(jù)很大時,這可能會在頁面載入時造成明顯的性能壓力。3.x 版本,只會對「被用于渲染初始可見部分的數(shù)據(jù)」創(chuàng)建觀察者,而且 3.x 的觀察者更高效。
更精準(zhǔn)的變更通知。
比例來說:2.x 版本中,使用 Vue.set來給對象新增一個屬性時,這個對象的所有 watcher都會重新運行;3.x 版本中,只有依賴那個屬性的 watcher才會重新運行。
vue2和vue3生命周期鉤子函數(shù)的不同
Vue2--------------vue3
beforeCreate -> setup()
created -> setup()
beforeMount -> onBeforeMount
mounted -> onMounted
beforeUpdate -> onBeforeUpdate
updated -> onUpdated
beforeDestroy -> onBeforeUnmount
destroyed -> onUnmounted
activated -> onActivated
deactivated -> onDeactivated
errorCaptured -> onErrorCaptured
vue2中的生命周期
beforeCreate 組件創(chuàng)建之前
created 組件創(chuàng)建之后
beforeMount 組價掛載到頁面之前執(zhí)行
mounted 組件掛載到頁面之后執(zhí)行
beforeUpdate 組件更新之前
updated 組件更新之后
vue3中的生命周期
setup 開始創(chuàng)建組件
onBeforeMount 組價掛載到頁面之前執(zhí)行
onMounted 組件掛載到頁面之后執(zhí)行
onBeforeUpdate 組件更新之前
onUpdated 組件更新之后
而且Vue3.x 生命周期在調(diào)用前需要先進(jìn)行引入。
如:
import {
reactive,
toRefs,
onMounted,
onBeforeMount,
onBeforeUpdate,
onUpdated,
} from "vue";
部分命令發(fā)生了變化:
下載安裝 npm install -g vue@cli
刪除了vue list
創(chuàng)建項目 vue create
啟動項目 npm run serve
默認(rèn)項目目錄結(jié)構(gòu)也發(fā)生了變化:
移除了配置文件目錄,config 和 build文件夾 移除了 static文件夾,新增 public文件夾,并且 index.html 移動到 public中 在 src 文件夾中新增了 views 文件夾,用于分類 視圖組件 和 公共組件
3.0 新加入了 TypeScript 以及 PWA 的支持