vue2.0与vue3.0的不同

139 阅读6分钟

API类型

通过vue2, vue3两种形式实现同一个需求,理解vue3的compition api 带来的好处 两个独立的功能: - 通过点击按钮来控制div的显示和隐藏 - 通过点击按钮控制div内字体颜色的变化

  • Vue2选项式API(option(选项) api) 优点:简单,各选项各司其职;缺点:不方便功能复用;功能代码分散维护代码横跳
  • Vue3组合式API(composition(组成) api) 优点:功能代码组合维护, 不方便功能复用;

选项式API

<template>
  <div>
    <!-- 功能一模板 -->
    <button @click="show">显示</button>
    <button @click="hide">隐藏</button>
    <div class="box" v-if="showDiv">一个被控制显隐的div</div>
  </div>
  <div>
    <!-- 功能二模板 -->
    <button @click="changeRed">红色</button>
    <button @click="changeYellow">蓝色</button>
    <div class="box" :style="`color:${fontColor}`">一个被控制字体颜色的的div</div>
  </div>
</template>
<style scoped>
.box{width:200px;height: 200px;line-height:200px;background-color: cornflowerblue;text-align: center;}
</style>
<script>
export default {
  name: 'App',
  data() {
    return {
      showDiv: true, // 功能一数据
      fontColor: '' // 功能二数据
    }
  },
  methods: {
    // 功能一方法
    show() {
      this.showDiv = true
    },
    hide() {
      this.showDiv = false
    },
    // 功能二方法
    changeRed() {
      this.fontColor = 'red'
    },
    changeYellow() {
      this.fontColor = 'blue'
    }
  }
}
</script>

组合式API

<script>
import { ref } from 'vue'

function useShow() {
  const showDivFlag = ref(true)
  function show() {
    showDivFlag.value = true
  }
  function hide() {
    showDivFlag.value = false
  }
  return { showDivFlag, show, hide }
}

function useColor() {
  const fontColor = ref('')
  function changeRed() {
    fontColor.value = 'red'
  }
  function changeBlue() {
    fontColor.value = 'blue'
  }
  return { fontColor, changeRed, changeBlue }
}

export default {
  name: 'App',
  setup() {
    // 功能一
    const { showDivFlag, show, hide } = useShow()
    // 功能二
    const { fontColor, changeRed, changeBlue } = useColor()
    
    return { showDivFlag, show, hide, fontColor, changeRed, changeBlue }
  }
}
</script>

生命周期

添加图片注释,不超过 140 字(可选)

Vue2Vue3组合式api写法
创建 —— 创建实例之前;data 和 methods 中的 数据都还没有没初始化beforeCreatebeforeCreate
创建 —— 实例创建之后; data 和 methods 都已经被初始化好了createdcreated
挂载 —— 挂载前;模板已经在内存中编译好了 但未挂载 页面还是旧的beforeMountbeforeMountonBeforeMount
挂载 —— 挂载后;只要执行完了 mounted,就表示 整个Vue 实例已经初始化完毕了mountedmountedonMounted
更新 —— 数据变化时;页面中的显示的数据是旧的 数据是最新的 页面尚未和最新的数据保持同步beforeUpdatebeforeUpdateonBeforeUpdate
更新 —— 数据变化后;页面和数据已经保持同步更新了updateupdateonUpdate
销毁 —— 此时实例身上所有的数据 、方法、过滤器、指令等处于可用状态,没有真正执行销毁过程beforeDestrorybeforeUnmountonBeforeDestrory
销毁 —— 实例被完全销毁之后destroyedunmountedonDestroyed

Router

路由传参和vue2.0的区别在于setup中不能访问this

(这部分还没有整理......)

模版指令

v-model

  • vue3新增:现在可以在同一个组件上使用多个 v-model 绑定;
  • vue3新增:现在可以自定义 v-model 修饰符。

v-for v-if 优先级

  • Vue2中 v-for 优先级更高
  • Vue3中 v-if 优先级更高

v-bind

vue2

vue3

v-key

  • Vue2 for循环需要加key。Vue3不需要加
  • 原因:vue3更新了虚拟dom算法。每个节点都有身份跟踪

v-on.native

vue3.0中删除 .native

所有组件都使用emits选项记录事件。

添加图片注释,不超过 140 字(可选)

其他点

Diff算法

vue2.0

  • 双端diff算法
  • 虚拟dom进行全量对比
  • 无论元素是否参与更新,每次都会被重新创建再进行渲染

vue3.0

  • 最长递增子序列
  • 新增了静态标记 只对带有PatchFlag的节点
  • Vue3对不参与更新的元素只做静态几天 只会创建一次 渲染时直接复用即可

响应式系统

vue2.0

  • 利用ES5的Object.definePropert()对数据劫持 结合发布订阅模式
  • 需要使用 push、shift、pop、splice、unshift、sort、resvers 检测数组变化

vue3.0

  • 利用ES6的Proxy API对数据代理,能更好支持动态添加属性和删除属性
  • 无需在检测数组变化

根节点

vue2.0 只能一个根节点;vue3.0 支持多个根节点

Typescript支持

vue2.0 需要额外配置;vue3.0 是原生可以支持

插槽

vue2.0可以直接使用slot;vue3.0必须使用v-slot的形式

函数式组件

指的是没有状态的组件。本质上是一个普通函数,该函数返回值是一个虚拟dom。通过静态属性的形式添加 props 属性

  • Vue2中是作为性能优化,因为它们的初始化速度比有状态组件快得多
  • Vue3中官网和书中都提到过,相比有状态组件性能提升微乎其微 。即使是有状态的组件,初始化性能消耗也非常小,用它就是简单性。

特点

  • 没有任何管理状态
  • 没有监听任何给他传递的状态
  • 本身没有实例(this)
  • 没有生命周期
  • 只能接收一些prop数据

vue3.0新特性

setup函数的特点

setup()函数接收两个参数:props、context(包含attrs、slots、emit)。 setup函数是处于生命周期beforeCreated和created俩个钩子函数之前。 执行setup时,组件实例尚未被创建(在setup()内部,this不指向vue实例,避免我们错误得使用,直接将setup函数中得this修改成了undefined)。 - Vue 3提供的getCurrentInstance函数来获取当前组件实例 与模板一起使用时,需要返回一个对象。 因为setup函数中,props是响应式得,当传入新的prop时,它将会被更新,所以不能使用es6解构,因为它会消除prop得响应性,如需解构prop,可以通过使用setup函数中得toRefs来完成此操作。 - 使用ES6的解构语法会消除prop的响应性,因为它会将prop的值解构为一个新的变量。为了保留prop的响应性,我们可以使用setup函数中的toRefs函数。toRefs函数会将一个响应式对象转换为普通对象,其中每个属性都是一个ref对象。这些ref对象是响应式的,因此当我们访问它们的value属性时,我们可以获得响应式更新 从setup() 中返回得对象上得property 返回并可以在模板中被访问时,它将自动展开为内部值。不需要在模板中追加.value。 setup函数只能是同步的不能是异步的。

Teleport组件

作用:跨越dom层级完成渲染。很像哆啦A梦的任意门 原理:把teleport组件的渲染逻辑从渲染器中抽离,在指定位置独立渲染

抽离的好处:

  • 避免渲染器逻辑代码‘膨胀’
  • 可以利用Tree-Shaking机制在最终的bundle中删除Teleport相关代码,使得最终构建包的体积变小

emits —添加自定义事件作为触发组件的条件

异步组件 defineAsyncComponent()

会返回一个promise 使用场景 可以是数据加载前loading组件 或者报错组件

自定义渲染器api createRender()

Tree-shaking 摇树优化

是基于ES6模板语法(import与exports),主要是借助ES6模块的静态编译思想,在编译时就能确定模块的依赖关系。

  • 在2.x版本中,很多函数都挂载在全局Vue对象上 因此虽然我们可能用不到,但打包时只要引入了vue这些全局函数仍然会打包。
  • 而在Vue3中,所有的API都通过ES6模块化的方式引入,这样就能让webpack或rollup等打包工具在打包时对没有用到API进行剔除。

原理

  • 编译阶段利用ES6 Module判断哪些模块已经加载
  • 判断那些模块和变量未被使用或者引用,进而删除对应代码

(持续更新)