Vue2&Vue3 区别

131 阅读3分钟

1. 全局API

image.png

可以看到,在Vue2中我们使用new Vue() 方式简单的创建了一个 Vue 的根实例, 而在Vue3中我们使用新的global API创建,即使用 createApp() 创建。Vue2在根上创建固然简单,但是使用可能会引起污染。所以 Vue3 使用实例创建,如果想要使用其他方法,为避免污染,可以新创建一个实例,将需要的方法绑定到新实例上即可。

2. v-model双向绑定

prop: value -> modelValue;

event: input -> update:modelValue

v-bind的sync修饰符以及model 选项被移除了,使用 v-model 代替。此外,在同一个组件上可以绑定多个 v-model,还可以自定义 v-model 修饰符。

3. v-if & template

v-if/v-else/v-else-if 移除了 key 值,template 使用 v-for 后,将 key 属性放到 template 上即可,而不需要放到它的子节点上。

4. v-if & v-for

如果在同一个元素上同时使用,v-if 将比 v-for 有更高的优先级。

5. v-bind 合并

在 vue2 中,v-bind 和相同属性值同时存在,单独的属性值会一直覆盖掉 v-bind 中的对象值。在 vue3 中,跟书写的顺序有关,后面的会替换掉前面的。

6. native修饰符

v-on.native 修饰符被移除。与此同时,emits 参数允许子组件定义的确需要传递的事件。

7. 渲染函数

7.1 组件参数

Vue2的渲染函数有3个参数:props、data、children;3变成了两个参数:props、context,listeners 被添加到了 attrs 属性中,已经被移除。 Vue2的:

image.png

image.png

Vue3:

image.png

image.png

7.2 同步组件

  • 新的方法 defineAsyncComponent 显示定义同步组件
  • 组件选项重命名为 loader
  • 加载函数并不继承接收 resolve 和 reject 参数,而是必须要返回一个 Promise 对象。

7.3 emits

Vue3 中的 emits 事件需要声明,用法和 props 相同,可以定义为数组和对象,定义为对象时增加了验证。

父组件在执行子组件 emits 的事件时,会执行两次:一次是原生的;另外一次是父组件监听后执行的事件。为解决这个问题,有两种方法:1. 在正确的地方声明点击事件;2. 子组件移除 emits 事件。

image.png

8. 插槽

  • this.$slots 被作为一个函数暴露出去
  • this.$scopedSlots 被移除

9. attrs 包含 class 和 style

10. teleport & suspence

11. setup

在 script 中声明为 setup 语法后,不需要使用 data、methods 等方式声明了,直接定义即可。

12. Fragment

在使用 template 模板时,可以包含多个一级元素节点了

13. 生命周期钩子

  • Vue2:

    • beforeCreate
    • created
    • beforeMount
    • mounted
    • updated
    • beforeDestroy
    • destroyed
    • errorCaptured
    • activated
    • deactivated
  • Vue3:

    • onBeforeMount
    • onMounted
    • onBeforeUpdate
    • onUpdated
    • onBeforeUnmount
    • onUnmounted
    • onErrorCaptured
    • onActivated
    • onDeactivated

14. 响应式原理

vue2的响应式原理是靠 Object.defineProperty 实现的,vue3 是通过 Proxy 来实现的。

vue2:

  • 需要提前递归地遍历 data 做到响应式

  • 无法跟踪到对象增加新值,删除属性

    • 因为 Object.defineProperty 是属性层级的api。只能拦截对象的某个属性,所以只能遍历需要监听对象的属性来跟踪。因此监听不了新增属性。
    • 而 Object.defineProperty api本身无法跟踪对象删除属性,所以 Vue2 中,提供了 setset 和 delete
  • 数组需要额外处理 image.png

    • 数组处理思想:创建一个指向 Array.prototype 的对象,在这个对象中创建 vue2 中那七个 api 属性。其每个属性是调用 Array.prototype 上的 api,同时可实现跟踪。最后,将监听的数组使其原型指向这个创建的对象。
      function trackArray(arr) {
        const prototype = Array.prototype
        const newProto = Object.create(prototype)
        const methods = ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse']
        methods.forEach(item => {
          newProto[item] = function(...args) {
            prototype[item].call(arr, ...args)
            console.log('call ', item)
          }
        })
        arr.__proto__ = newProto
      }
    

vue3:

  • 可以很完备的监听到属性增加和删除
  • 数组可以使用原生api,不需要再对需要监听的api做单独处理
  • 在获取值的时候才对其进行监听(按需监听)
  • 使用 Proxy 可以解决 vue2 出现的问题

具体可以可以查看此文章