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 字(可选)
| Vue2 | Vue3 | 组合式api写法 | |
|---|---|---|---|
| 创建 —— 创建实例之前;data 和 methods 中的 数据都还没有没初始化 | beforeCreate | beforeCreate | |
| 创建 —— 实例创建之后; data 和 methods 都已经被初始化好了 | created | created | |
| 挂载 —— 挂载前;模板已经在内存中编译好了 但未挂载 页面还是旧的 | beforeMount | beforeMount | onBeforeMount |
| 挂载 —— 挂载后;只要执行完了 mounted,就表示 整个Vue 实例已经初始化完毕了 | mounted | mounted | onMounted |
| 更新 —— 数据变化时;页面中的显示的数据是旧的 数据是最新的 页面尚未和最新的数据保持同步 | beforeUpdate | beforeUpdate | onBeforeUpdate |
| 更新 —— 数据变化后;页面和数据已经保持同步更新了 | update | update | onUpdate |
| 销毁 —— 此时实例身上所有的数据 、方法、过滤器、指令等处于可用状态,没有真正执行销毁过程 | beforeDestrory | beforeUnmount | onBeforeDestrory |
| 销毁 —— 实例被完全销毁之后 | destroyed | unmounted | onDestroyed |
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判断哪些模块已经加载
- 判断那些模块和变量未被使用或者引用,进而删除对应代码
(持续更新)