Vue3.x
对比Vue2.x, Vue3.x变化在哪里
diff算法
Vue 2 递归双指针遍历diff算法,它会遍历新旧两个虚拟节点树的每一层,进行逐个对比。
Vue 3 引入了 patch flag 的概念,并且对 diff 算法进行了优化,基于数组的动态规划的 diff 算法,比如在相同层级的元素间进行移动时,Vue 3 可以更高效地处理这种情况。
具体的优化点包括:
Vue 3 中会根据 patch flag 判断节点类型,如果是同类型节点则可以直接复用老节点的内容,只需对比新旧节点的 data 和 children 是否有变化。
Vue 3 中使用了 Fragments,可以让多个节点复用同一个 DOM 元素,无需额外标签。
// 假设的 Vue 2 diff 算法
function diff(oldTree, newTree) {
// 遍历比较整个虚拟 DOM 树
// ...
}
// 假设的 Vue 3 diff 算法
function patch(oldNode, newNode) {
const patchFlag = newNode.patchFlag;
if (patchFlag === PATCH_FLAG_TYPE_TEXT) {
// 文本节点,直接更新内容
oldNode.textContent = newNode.text;
} else if (patchFlag === PATCH_FLAG_FULL_PROPS) {
// 全新的属性,需要更新所有属性
// ...
} else if (patchFlag === PATCH_FLAG_HYDRATE_EVENTS) {
// 需要处理事件绑定
// ...
}
// ...
}
Vue3通常会更高效,因为它减少了不必要的 DOM 操作,并且对特定类型的更改做了优化处理。
架构部分
TreeShaking TypeScript
新增特性
- framents
模板支持多个根节点
- Teleport
将我们的模板移动到 DOM 中 Vue app 之外的其他位置
createRenderer
Composition API
不兼容的change
生命周期区别:
Vue2.x:beforeDestroy, destroyed Vue3.x: beforeUnmount, unmounted
1.Global API 全局 Vue API 已更改为使用应用程序实例 全局和内部 API 已经被重构为可 tree-shakable 2.模板指令 组件上 v-model 用法已更改 在同一元素上使用的 v-if 和 v-for 优先级已更改: 虽然Vue 3仍然允许在同一个元素上同时绑定v-for和v-if(尽管不推荐),但执行顺序变为v-if优先于v-for v-bind="object" 现在排序敏感 v-for 中的 ref 不再注册 ref 数组: 需要主动将 ref 绑定到一个更灵活的函数上 3.组件 只能使用普通函数创建功能组件 functional 属性在单文件组件 (SFC) 异步组件现在需要 defineAsyncComponent 方法来创建 4.渲染函数 渲染函数API改变 $scopedSlots property 已删除,所有插槽都通过 $slots 作为函数暴露 自定义指令 API 已更改为与组件生命周期一致 一些转换 class 被重命名了: 1.v-enter -> v-enter-from 2.v-leave -> v-leave-from 组件 watch 选项和实例方法 $watch 不再支持点分隔字符串路径,请改用计算函数作为参数 在 Vue 2.x 中,应用根容器的 outerHTML 将替换为根组件模板 (如果根组件没有模板/渲染选项,则最终编译为模板)。Vue3.x 现在使用应用程序容器的 innerHTML。 5.其他小改变 destroyed 生命周期选项被重命名为 unmounted beforeDestroy 生命周期选项被重命名为 beforeUnmount prop default工厂函数不再有权访问 this 是上下文 自定义指令 API 已更改为与组件生命周期一致 data 应始终声明为函数 来自 mixin 的 data 选项现在可简单地合并 attribute 强制策略已更改 一些过渡 class 被重命名 组建 watch 选项和实例方法 $watch 不再支持以点分隔的字符串路径。请改用计算属性函数作为参数。
<template>
没有特殊指令的标记 (v-if/else-if/else、v-for 或 v-slot) 现在被视为普通元素,并将生成原生的<template>
元素,而不是渲染其内部内容。 在Vue 2.x 中,应用根容器的 outerHTML 将替换为根组件模板 (如果根组件没有模板/渲染选项,则最终编译为模板)。Vue 3.x 现在使用应用容器的 innerHTML,这意味着容器本身不再被视为模板的一部分。 5.移除 API keyCode 支持作为 v-on 的修饰符 $on , $off 和 $once 实例方法 过滤 filter 内联模板 attribute $destroy 实例方法。用户不应再手动管理单个Vue 组件的生命周期。
.env
.env.development和.env.production环境配置文件中变量名必须以VUE_APP_开头
深度选择器
/deep/
<style scoped> .parent /deep/ .child { } </style>
>>>
<style scoped> .parent /deep/ .child { } </style>
::v-deep
v-deep()
:deep() {}