Vue2和Vue3的区别

130 阅读1分钟

1.Vue 3.x 中使用了 Proxy 作为响应式,天生的代理,不用考虑属性重写、数组这些2.x 中hack的情况;

  • vue2自己实现代理
// vm.$data.key => vm.key
function proxy(target, data) {
  Object.keys(data).forEach((key) => {
    Object.defineProperty(target, key, {
      configurable: true,  // 控制属性是否可以被删除
      enumerable: true,  // 控制属性是否可以枚举
      get() {
        return data[key];
      },
      set(newVal) {
        if (!isSameVal(data[key], newVal)) {
          data[key] = newVal;
        }
      }
    })
  })
}
  • vue3直接用Proxy和Reflect
export function reactive(data) {
  if (!isObject(data)) return;
  return new Proxy(data, {
    get(target,key,receiver){
      const ret = Reflect.get(target,key,receiver);
      return isObject(ret) ? reactive(ret) : ret;
    },
    set(target,key,value,receiver) {
      Reflect.set(target,key,value,receiver);
      return true;
    }
  })

}

2.diff增加了最大递增子序列的算法,让我移动节点,更高效;

 /**
           * 我们现在假设,中间部分不一样的数组是:[c, d, e] 和 [d, e, h, c]
           * {d:2, e:3, h:4, c:5}
           
           * c -- 3 -- newIdx[3] = 3(第一个数组中的索引+1) 
           * d -- 0 -- newIdx[0] = 4
           * e -- 1 -- newIdx[1] = 5 
           * 数组就变成了: [4, 5, 0, 3]
           * 4,5 是上升子序列,看看,是不是就对应着,可以不移动的。d 和 e
           * 
           * [1,5,2,4,6,0,7]  寻找最长上升子序列。
           * 【1,2,4,6,7】
           */

3. 架构采用 monorepo 的方式,分层清晰,同时把编译部分也进行了一些拆解;

  • 各个项目单独打包,但又可以相互引用,共同存在于一个仓库中

4.vue3 对编译的内容,进行了重写,template -- render 函数。

  • vue2 正则, vue3 状态机; -- [ast 编译原理]
  • patchFlag, 标记哪些元素包含哪些属性
  • 静态提升

5.vue3 使用 blockTree, 对比需要改变的,优化性能,如果你要用 jsx 的写法,就不会优化,但是可以自己去标记。

6.ts 重构。

7.compiler 拆成了四个包。方便你去重写。

8.vue2 options API -- vue3 composition API

9.vue3,使用了 rollup 打包,支持 treeshaking。

10.实例化方式也有区别

  • vue2通过new Vue()构造函数的方式来创建实例
const app = new Vue({
    el: '#app',
    data: {
        message: 'hello world!'
    }
})
// 或者
import APP from './APP.vue'

const vm = new Vue({
    render:h => h(APP)
})
vm.$mount('#app')
  • vue3
const app = Vue.createApp({
   //...
})
app.mount('#app')


// 或者
import {createApp} from 'vue'
import APP from './APP.vue'

const app = createApp(APP)
app.mount('#app')