1. 雙向數(shù)據(jù)綁定原理(數(shù)據(jù)劫持方式)不同
Vue2 使?的是
Object.defineProperty()
進?數(shù)據(jù)劫持胖眷,結(jié)合發(fā)布訂閱的?式實現(xiàn)孽椰。
- 缺點
1.初始化的時候遞歸遍歷會造成性能損失
2.新增或刪除屬性時需要用戶使用Vue.set/delete這樣的特殊api才能生效
3.對于es6中的Map,Set這些數(shù)據(jù)結(jié)構(gòu)不支持等問題
Vue3 使?的是
Proxy
代理臂拓,使?ref
或者reactive
將數(shù)據(jù)轉(zhuǎn)化為響應(yīng)式數(shù)據(jù)
- 優(yōu)勢
- Object.defineProperty是監(jiān)聽屬性叹谁,只能攔截對象的屬性訪問和修改矢腻。Proxy 可以對整個對象監(jiān)聽瓶殃,可以攔截對象的所有操作。
- 可以省去for in螺戳,閉包等內(nèi)容來提升效率(直接綁定整個對象即可)
- 可以監(jiān)聽數(shù)組搁宾,不用再去單獨的對數(shù)組做特異性操作
2. 是否支持碎片
- vue2不支持碎片
- vue3支持碎片(Fragments) 折汞,就是說可以擁有多個根節(jié)點倔幼。
3. 組件模板是否有唯一頂層元素的限制
- vue2要求必須有一個唯一的頂層元素包裹
<template>
<div>
<h1>第三界面</h1>
<button>測試 </button>
</div>
</template>
- vue3沒有
<template>
<h1>第三界面</h1>
<button>測試 </button>
</template>
3. API類型不同
- vue2:
vue2使用選項類型api,選項型api在代碼里分割了不同的屬性:data,computed,methods等爽待。 - vue3:
vue3使用組合式api损同,數(shù)據(jù)和?法都定義在setup中,并統(tǒng)?進?return{} ,相比于舊的api使用屬性來分組鸟款,這樣代碼會更加簡便和整潔膏燃。- v3可以使用各種組合式API 寫法更接近于 React
- this基本不使用
- 都是通過hook的形式使用
- setUp的使用
import {useRoute,useRouter} from "vue-router" 路由
import { onMounted, reactive ,defineProps,defineEmits,useContext} from "vue";
import {useStore} from 'vuex' //存儲
const store = useStore()
Object.assign(userInfo, res.data);
console.log("userInfo", userInfo);
store.commit("updateUserInfo",userInfo)
//響應(yīng)式數(shù)據(jù)
let res = reactive({
list1:[]
})
// 鉤子
onMounted(() => {
})
//插槽 組件上的屬性
const {slots,attrs} = useContext()
// props 組件傳參
const props = defineProps({
num: Number,
});
//事件 觸發(fā)
const emit = defineEmits(["change"]);
let changeNum = () => {
emit("change", 10);
};
let route = useRoute()
let router = useRouter()
4. 定義數(shù)據(jù)變量和方法不同
- vue2:vue2是把數(shù)據(jù)放入data中,創(chuàng)建的方法要在methods
中何什。 - vue3:vue3就需要使用一個新的setup()方法组哩,此方法在組件初始化構(gòu)造的時候觸發(fā)。使用以下三個步驟來建立反應(yīng)性數(shù)據(jù):
- 從vue引入reactive处渣;
- 使用reactive() 方法來聲明數(shù)據(jù)為響應(yīng)性數(shù)據(jù)伶贰;
- 使用setup()方法來返回我們的響應(yīng)性數(shù)據(jù),從而template可以獲取這些響應(yīng)性數(shù)據(jù)罐栈。
5. 生命周期鉤子函數(shù)不同
vue2中的生命周期:
- beforeCreate 組件創(chuàng)建之前
- created 組件創(chuàng)建之后
- beforeMount 組價掛載到頁面之前執(zhí)行
- mounted 組件掛載到頁面之后執(zhí)行
- beforeUpdate 組件更新之前
- updated 組件更新之后
vue3中的生命周期:
- setup 開始創(chuàng)建組件前
- onMounted()
- onUpdated()
- onUnmounted()
- onBeforeMount()
- onBeforeUpdate()
- onBeforeUnmount()
- onErrorCaptured()
- onRenderTracked()
- onRenderTriggered()
- onActivated()
- onDeactivated()
- onServerPrefetch()
而且vue3.x 生命周期在調(diào)用前需要先進行引入黍衙。
廢棄了beforeCreate和created,用setup
廢棄了beforeDestroy 用beforeUnmount
廢棄了destroyed 用unmounted
6. 父子傳參不同
- vue2:
獲取props:console.log(‘props’,this.xxx)
給父組件傳值emit :this.$emit()
- vue3:
獲取props:setup(props,context){ console.log(‘props’,props) }
給父組件傳值emit :setup(props,context){context.emit()}
export default {
emits: ['inFocus', 'submit'],
setup(props, ctx) {
ctx.emit('submit')
}
}
// 與 setup() 上下文對象中的其他屬性一樣荠诬,emit 可以安全地被解構(gòu):
export default {
emits: ['inFocus', 'submit'],
setup(props, { emit }) {
emit('submit')
}
}
7. 指令不同
- vue2:
v-for與v-if在vue2中優(yōu)先級高的是v-for指令琅翻,而且不建議一起使用位仁。 - vue3:
vue3中v-if比v-for優(yōu)先級高;vue3中移除keyCode作為v-on的修飾符方椎,當(dāng)然也不支持config.keyCodes聂抢;vue3中移除v-on.native修飾符;vue3中移除過濾器filter棠众。
8涛浙、main.js文件不同
- vue2:
- vue2中我們可以使用pototype(原型)的形式去進行操作,引入的是構(gòu)造函數(shù)摄欲。
- v2 el掛載
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
- vue3:
- vue3中需要使用結(jié)構(gòu)的形式進行操作轿亮,引入的是工廠函數(shù);vue3中app組件中可以沒有根標(biāo)簽胸墙。
- v3 mount 掛載
import './assets/main.css'
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
import router from './router'
const app = createApp(App)
app.use(createPinia())
app.use(router)
app.mount('#app')
9. 支持TS
- vue2 no
- vue3 yes
10. Diff 算法的提升
vue3 在 vue2 的 diff 算法的基礎(chǔ)上增加了靜態(tài)標(biāo)記我注,元素提升和事件緩存等優(yōu)化。使得速度更快迟隅。
11. 打包體積變化
vue2 官方說的運行時打包師 23k但骨,但這只是沒安裝依賴的時候,隨著依賴包和框架特性的增多智袭,有時候不必要的奔缠,未使用的代碼文件都被打包了進去,所以后期項目大了吼野,打包文件會特別多還很大校哎。
在 Vue 3 中,我們通過將大多數(shù)全局 API 和內(nèi)部幫助程序移動到 Javascript 的 module.exports 屬性上實現(xiàn)這一點瞳步。這允許現(xiàn)代模式下的 module bundler 能夠靜態(tài)地分析模塊依賴關(guān)系闷哆,并刪除與未使用的 module.exports 屬性相關(guān)的代碼。模板編譯器還生成了對樹抖動友好的代碼单起,只有在模板中實際使用某個特性時抱怔,該代碼才導(dǎo)入該特性的幫助程序。
盡管增加了許多新特性嘀倒,但 Vue 3 被壓縮后的基線大小約為 10 KB屈留,不到 Vue 2 的一半
12. vue3新增組件
-
<Teleport>
Teleport 是一種能夠?qū)⑽覀兊哪0逡苿拥?DOM 中 Vue app 之外的其他位置的技術(shù),就有點像哆啦A夢的“任意門”
在vue2中测蘑,像 modals,toast 等這樣的元素灌危,如果我們嵌套在 Vue 的某個組件內(nèi)部,那么處理嵌套組件的定位帮寻、z-index 和樣式就會變得很困難
通過Teleport乍狐,我們可以在組件的邏輯位置寫模板代碼,然后在 Vue 應(yīng)用范圍之外渲染它
<button @click="showToast" class="btn">打開 toast</button>
<!-- to 屬性就是目標(biāo)位置 -->
<teleport to="#teleport-target">
<div v-if="visible" class="toast-wrap">
<div class="toast-msg">我是一個 Toast 文案</div>
</div>
</teleport>
-
<Suspense>
<Suspense> 可以在等待整個多層級組件樹中的各個異步依賴獲取結(jié)果時固逗,在頂層展示出加載中或加載失敗的狀態(tài)浅蚪。
13. vue3 setup()函數(shù)特性
- setup()函數(shù)接收兩個參數(shù):props藕帜、context(包含attrs、slots惜傲、emit)洽故。
- setup函數(shù)是處于生命周期beforeCreated和created倆個鉤子函數(shù)之前。
- 執(zhí)行setup時盗誊,組件實例尚未被創(chuàng)建(在setup()內(nèi)部时甚,this不會是該活躍實例得引用,即不指向vue實例哈踱,Vue為了避免我們錯誤得使用荒适,直接將setup函數(shù)中得this修改成了undefined)。
- 與模板一起使用時开镣,需要返回一個對象刀诬。
- 因為setup函數(shù)中,props是響應(yīng)式得邪财,當(dāng)傳入新的prop時陕壹,它將會被更新,所以不能使用es6解構(gòu)树埠,因為它會消除prop得響應(yīng)性糠馆,如需解構(gòu)prop,可以通過使用setup函數(shù)中得toRefs來完成此操作怎憋。
- 在setup()內(nèi)使用響應(yīng)式數(shù)據(jù)時又碌,需要通過 .value 獲取。
- 從setup() 中返回得對象上得property 返回并可以在模板中被訪問時盛霎,它將自動展開為內(nèi)部值赠橙。不需要在模板中追加.value耽装。
- setup函數(shù)只能是同步的不能是異步的愤炸。