文章目錄
- vue2和vue3的區別
- 1. 實現數據響應式的原理不同
- 2. 生命周期不同
- 3. vue 2.0 采用了 option 選項式 API,vue 3.0 采用了 composition 組合式 API
- 4. 新特性編譯宏
- 5. 父子組件間雙向數據綁定 v-model 不同
- 6. v-for 和 v-if 優先級不同
- 7. 使用的 diff 算法不同
- 8. 兄弟組件間的通信 eventBus
- 9. vue 3.0 提供了 TypeScript 支持
- 10. 腳手架不同
- 11. 獲取 DOM 的方法不同
- 12. vue-router 的使用細節
- 13. vuex 與 pinia
- 14. vue 3.0 廢除了 filters 過濾器的使用
- 15. template 模版中根標簽的問題
- 16. 語法細節的不同
vue2.0和3.0語法不同,使用時一定要先看版本。
現在主流都是用3.0,所以2.0單獨拿出來。
vue2和vue3的區別
1. 實現數據響應式的原理不同
① vue 2.0:
通過 es5 的語法 Object.defineProperty(),數據劫持的方式實現數據的響應式。
② vue 3.0:
通過 Proxy 代理對象的方式實現數據的響應式。
因此,又多了一些定義響應式數據的方法,如 ref、reactive、roRef、toRefs。
ref:接收簡單類型或者對象類型的數據傳入并返回一個響應式的對象。(RefImpl)修改值,獲取值的時候,需要.value。
reactive:接受對象類型數據的參數傳入并返回一個代理響應式的對象。(Proxy)
toRef:轉換響應式對象中某個屬性為單獨響應式數據,并且值是關聯的。
toRefs:轉換響應式對象中所有屬性為單獨響應式數據,并且值是關聯的。
2. 生命周期不同
① vue 2.0 一共 10 個生命周期
beforeCreate
created
beforeMount
mounted
beforeUpdate
updated
activated:keep-alive 組件緩存技術,激活
deactivated:keep-alive 組件緩存技術,未激活
beforeDestroy
destroyed
② vue 3.0 一共 7 個生命周期
setup
onBeforeMount
onMounted
onBeforeUpdate
onUpdated
onBeforeUnmount
onUnmounted
總結:
廢棄了 activated、deactivated 生命周期函數。
setup 函數是整個組件的起點,執行時機在 beforeCreate 之前,所以沒有辦法拿到當前組件實例 this。
但是 setup 函數里可以接收兩個形參 props 和 context。
props 為屬性
context 為當前組件實例,也是就相當于vue 2.0 中的 this。
vue 3.0 中的生命周期函數使用函數調用的方式執行,所以可以多次調用執行。
3. vue 2.0 采用了 option 選項式 API,vue 3.0 采用了 composition 組合式 API
① option API
數據定義在 data 里,屬性定義在 props 里,計算屬性定義在 computed 里,方法定義在 methods 里。
相較于 vue 3.0 則更易于學習和使用。
② composition API
一個功能邏輯的代碼組合在一起。
相較于 vue 2.0 更易于閱讀和維護。
小插曲,談一談自己對于 vue 2.0 和 vue 3.0 的選項式 API 和組合式 API 的理解:
vue 3.0 是在 2020 年 10 月發布的。由于寫 vue 2.0 的時間比較早,所以當時在轉入 vue 3.0 的時候,并沒有花太多時間。感受最深的一點就是,在 vue 3.0 中無法使用 this,前文已經談過 this 的問題,在這里不再贅述。而 vue 3.0 也可以分為兩個版本,vue 3.3 以下的版本,其實感覺還是 option API 的寫法,因為在 setup 函數平級的節點中,依然可以定義 props 和 components 節點,只不過是把數據和方法定義在 setup 函數里,然后通過 return 出來使用。
在 vue 3.3 及 3.3 以上的版本中,引入了
4. 新特性編譯宏
常用的編譯宏如下:
defineProps:定義屬性
defineEmits:定義自定義的事件的觸發
defineExpose:向外暴露組件的屬性和方法
在非語法糖的寫法中,通過 setup 函數的 return 出來了屬性和方法,所以無須使用defineExpose
defineOptions:向外暴露組件的一些自定義屬性,如 name
defineModel:vue 3.0 中父子組件間的雙向數據綁定
const modelValue = defineModel()
5. 父子組件間雙向數據綁定 v-model 不同
① vue 2.0:
父組件默認傳遞的屬性是 value,子組件默認觸發的自定義事件是 input
② vue 3.0:
父組件默認傳遞的屬性是 modelValue,子組件默認觸發的自定義事件是 update:modelValue
6. v-for 和 v-if 優先級不同
vue 2.0 中 v-for 的優先級高
vue 3.0 中 v-if 的優先級高
7. 使用的 diff 算法不同
① vue 2.0
同級比較,根元素變化,整個 dom 樹刪除重建
根元素未變
屬性改變,更新屬性
子元素內容改變
無 key 就地更新
有 key 按 key 比較
② vue 3.0
將靜態節點與動態節點分離
通過高效標記和打補丁的方式,更新 dom
總結:
所以 vue 3.0 的渲染性能優于 vue 2.0
8. 兄弟組件間的通信 eventBus
vue 2.0 中的 eventBus 是一個 vue 的實例對象
vue 3.0 中的eventBus 是 mitt 庫
9. vue 3.0 提供了 TypeScript 支持
10. 腳手架不同
vue 2.0 的打包工具是 webpack
vue 3.0 的打包工具是 vite
11. 獲取 DOM 的方法不同
vue 2.0 直接綁定 ref,使用 this.ref.屬性名的方式直接獲取
vue 3.0 需要先定義 const box = ref(null),再進行綁定
12. vue-router 的使用細節
① vue 2.0
通過 this. r o u t e r 和 t h i s . router 和 this. router和this.route 拿到全局的路由對象和當前的路由對象
路由前置守衛
to: 即將要進入的目標 路由對象
from:當前導航正要離開的路由
next: Function: 一定要調用該方法來 resolve 這個鉤子。執行效果依賴 next 方法的調用參數。
next(): 放行路由跳轉
next(false):攔截路由跳轉
const router = new VueRouter({ … })
router.beforeEach((to, from, next) => {
// …
})
② vue 3.0
通過 const router = useRouter() 和 const route = useRoute() 拿到全局的路由對象和當前的路由對象
路由前置守衛
少了 next
return false 攔截回 from 的地址頁面
return undefined / true 直接放行
const router = createRouter({ … })
router.beforeEach((to, from) => {
// …
// 返回 false 以取消導航
return false
})
13. vuex 與 pinia
① vue 2.0 vuex
state 定義數據
mutations 執行同步代碼,修改 state 中的數據必須通過 mutations,在組件中通過 commit 提交 mutation 的方式
actions 執行異步操作,在組件中通過中通過 dispatch 派遣 action 的方式
getters 類似于 computed 計算屬性或者過濾器
modules 模塊化
② vue 3.0 pinia
將 mutations 和 actions 合二為一,不在區分同步和異步操作,去掉了 modules 模塊化的概念,每一個 store 都是一個獨立的模塊
提供了豐富的插件配置及配置對象,如在實現數據本地持久化上,可以通過插件直接配置 persist: true就可以直接實現。
當時寫 vue 2.0 的項目,記得是自己封裝了一個 get、set 操作 localstorage 的方法去實現本地數據的持久化
14. vue 3.0 廢除了 filters 過濾器的使用
15. template 模版中根標簽的問題
vue 2.0 中必須有一個根標簽元素,vue 3.0 則不用
16. 語法細節的不同
此外就是一些語法上的使用細節,不做深入比較闡述了。
如:vue 3.0 一般是通過 Createxxx 創建實例
CreateApp 創建 vue 實例,2.0代碼:
// app.js
new Vue({el: '#app', // 指定 Vue 實例掛載的元素data: {message: 'Hello Vue!' // 定義數據對象}
});
CreateRouter 創建路由對象,2.0代碼:
import Vue from 'vue';
import Router from 'vue-router';
Vue.use(Router);
CreatePinia 創建 pinia。