vue2 和 vue3 對比


一、Vue3的優點

  • 1、diff算法的提升

vue2中的虛擬DOM是全量的對比,也就是不管是寫死的還是動態節點都會一層層比較,浪費時間在靜態節點上。

vue3新增靜態標記(patchflag ),與之前虛擬節點對比,只對比帶有patch flag 的節點,可通過flag信息得知當前節點要對比的具體內容。

例如: 當代碼中包含數據時,會標記為動態。

  • 2、靜態提升

vue2不管是否參與更新,都會重新創建再渲染。

vue3對於不參與更新的元素,會做靜態提升,只被創建一次,在渲染時直接復用即可。

  • 3、事件偵聽器緩存。
  • 4、 ssr渲染
  • 5、更好的ts支持
  • 6、Composition Api

vue2的組件內部都是options api風格,也就是在data, methods, mounted等來組織代碼,這樣會讓邏輯很分散,每次變動需要反復查找位置。

vue3中使用setup,邏輯都放到里邊。

  • 7、更先進的組件

vue2不允許template下寫兩個組件,vue3允許,將為我們創建一個虛擬的Fragment節點。

  • 8、自定義渲染api
const { createApp } from 'vue'
import App from "./src/App"
createApp(App).mount(('#app')
  • 9、按需編譯,體積比vue2更小
  • 10.支持多根節點組件

 、響應式原理不同:

  • vue2實現雙向數據綁定原理,是通過ES5的Object.defineProperty,根據具體的key去讀取和修改。其中的setter方法來實現數據劫持,getter實現數據修改。但是必須要先知道攔截和修改的key,所以vue2對於新增的屬性無能為力,比如無法監聽屬性的新增和刪除,數組索引和長度的變更,解決方法使用Vue.set(object, properName,value)等嵌套對象添加響應式。 
function observe(obj, callback) {
    let newObj = {};
    Object.keys(obj).forEach((key) => {
        Object.defineProperty(newObj, key, {
            enumerable: true,
            configurable: true,
            get() {
                return obj[key];
            },
            set(val) {
                obj[key] = val;
                callback(key, val);
            }
        })
    })
    return newObj;
}
let obj = observe({ name: 'alan', age: '1888' }, (key, value) => { console.log(`打印${value}`) });
  •  在vue3中使用es5中得更快的proxy,替代了Object.defineProperty。proxy可以理解為在對象外加了一層攔截,任何人要訪問該對象,都要通過這層攔截。且proxy直接對對象攔截而非屬性,並返回一個對象,具有更好的響應式支持。

 

function obseve2(obj, callback) {
    return new Proxy(obj, {
        set(target, key, value) {
            target[key] = value;
            callback(key, value);
        },
        get(taget, key) {
            return taget[key];
        }
    }
    )
}
let obj2 = obseve2({ x: 1, y: 2 }, (key, value) => { console.log('坐標系') })

 

 

 

三、生命周期變化

 

 初始化加載順序:

setup => beforeCreate => created => onBeforeMount => onMounted

vue3壓縮后變快,很大程度是因為這些使用都需要引入了。

!!!  vue3中的核心api都支持了tree-shaking,這些api都是通過包引入的方式而不是直接在實例化時就注入,只會對使用到的功能或特性進行打包(按需打包),這意味着更多的功能和更小的體積。

四、mixins更改

 在vue2 使用mixins來實現相同邏輯的抽離,每個組件只需要引入mixins,就能實現復用。

創建js文件,寫入

export default {
  data(){
    return {}
  },
  methods:{},
  computed:{},
  filters:{},
  created(){},
  mounted(){
    console.log("我是mixins");
  }
}

使用方法:

引入js文件,寫入mixins:[ ]

缺點:mixins的聲明周期會和引入mixins的組件的生命周期整合在一起。且minxins的生命周期比組件調用快。組件的data,methods會覆蓋同名data,methods。

1.變量來源不明確(隱式傳入),不利於閱讀,使代碼變得難以維護。

2.多個mixins的生命周期會融合到一起運行,但是同名屬性、同名方法無法融合,可能會導致沖突。

3.mixins和組件可能出現多對多的關系,復雜度較高(即一個組件可以引用多個mixins,一個mixins也可以被多個組件引用)。

vue3中的改進:

自定義hook的作用類似vue2的mixin,封裝可復用的功能函數。

import { ref,computed } from "vue";

export  function useCount(){
    const num = ref(10);
    const doubles = computed(() => num.value * 2);
    return {
        num,
        doubles
    }
}
 import {useCount} from './useCount'

//初始化
const {num,doubles}=useCount();

 五、父子傳值的變化

在vue2中使用props傳值。

在vue3中依舊使用,但是傳值寫法有所變化。

vue3  父組件

 <page2 :name="ageRef" @clickParent="clickParent"></page2>

 function clickParent() {
      console.log('我想點擊父組件')
    }

子組件

<template>
    <div>
        我是子組件page2啊:
        <div @click="emitP">{{name}}</div>
    </div>
</template>
<script>
import { toRefs } from 'vue'
export default{
    props:{
        name: String,
    },
    setup(props,context){
        let {name}=toRefs(props);
        let {slots,emit}=context;
        function emitP(){
            emit('clickParent');
        }
        return{
            name,
            emitP
        }
    }
}
</script>

context:

包含 attrsslotsemit 等數據方法:

  • attrs:獲取組件上的屬性
  • slots:獲取 slot 插槽的節點
  • emit :emit 方法(子組件向父組件傳遞數據

setup 函數是 Vue3 中新增的一個生命周期函數,會在 beforeCreate 之前調用。因為此時組件的 data 和 methods 還沒有初始化,因此在 setup 中是不能使用 this 的。所以 Vue 為了避免我們錯誤的使用,它直接將 setup 函數中的 this 修改成了undefined。並且,我們只能同步使用setup函數,不能用async將其設為異步。

setup 函數接收兩個參數 props和 context, 語法為:setup(props,context){}

props

props 里面包含父組件傳遞給子組件的所有數據。在子組件中使用 props 進行接收。

props 是響應式的, 當傳入新的 props 時,會及時被更新。
由於是響應式的, 所以不可以使用 ES6 解構,解構會消除它的響應式。可以使用toRefs

provide,inject 父組件向子組件傳遞方法和數據

api均從vue中引入。

在父組件直接provide(‘別名’,變量或方法);

在子組件直接inject(‘別名’)

六、碎片化節點

在vue2中,template下只允許存在一個根節點,在vue3中可以有多個跟結點。

 

 

參考文章:

https://www.cnblogs.com/bingcola/p/15210566.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM