全局 API
全局 API 应用实例
- Vue.config -> app.config
- Vue.config.productionTip -> 移除
- Vue.config.ignoreElements -> app.config.compilerOptions.isCustomElement
- Vue.component -> app.component
- Vue.directive -> app.directive
- Vue.mixin -> app.mixin
- Vue.use -> app.use
- Vue.prototype -> app.config.globalProperties
- Vue.extend -> 移除
全局 API Treeshaking
- Vue.nextTick() -> nextTick()
- Vue.observable -> reactive()
- Vue.version -> version
- Vue.compile(仅完整构建版本)
- Vue.set(仅兼容构建版本)
- Vue.delete(仅兼容构建版本)
模板指令
v-model
参见 vue3.md 的 v-model 指令部分
key 使用改变
对于 v-if, v-else-if, v-else 的各分支项 key 将不再是必须的, Vue 会自动生成唯一的 key
v-if 和 v-for 优先级
两者作用于同一个元素上时,v-if 会拥有比 v-for 更高的优先级
v-bind 合并行为
v-bind 的绑定顺序会影响渲染结果
- vue 2.x 独立绑定的 attribute 会覆盖 v-bind 中的 attribute
- vue 3.x 根据声明顺序决定如何被合并
1 | <!-- 模板 --> |
v-on.native 移除
v-on 的 .native 修饰符被移除
- 确保所有组件都是用新增的
emits选项记录其事件
组件
函数式组件
函数组件将接收两个参数: props 和 context, context 是一个包含 attrs, slots, emit 属性的上下文对象
<template>中的functional属性被移除{functional: true}选项从通过函数创建的组件中移除listeners作为$attrs的一部分传递
1 | import { h } from 'vue'; |
异步组件
- 新增
defineAsyncComponent助手方法, 用于显式地定义异步组件 component选项重命名为loaderLoader函数本身不再接收resolve和reject参数,且必须返回一个 Promise
1 | // Vue 2.x |
emits 选项
新增项用来定义组件可以向其父组件触发的事件
渲染函数
概览
h函数现在为全局引入,不再作为render函数的参数隐式提供
1 | import { h } from 'vue'; |
- 更改渲染函数参数, 使其在有状态组件和函数组件的表现更加一致
- VNode Prop 格式化
1 | // 2.x |
注册组件
- Vue3.x
setup()中 VNode 是上下文无关的, 无法使用字符串 ID 隐式查找已注册的组件, 需要借助resolveComponent方法
- Vue3.x
1 | // Vue 2.x |
插槽统一
this.$slots插槽作为函数公开this.$scopedSlots移除
$listeners 移除
$listeners对象在 Vue3 中被移除, 事件监听器现在是$attrs的一部分
$attrs 包含 class 和 style
$attrs 现在包含了所有传递给组件的 attribute, 包含 class 和 style
- Vue 2.x 当
inheritAttrs: false时,class和style不是$attrs的一部分, 仍然会被应用到组件的根元素中
自定义元素
与自定义元素的互操作性
特殊的
is属性的使用被严格限制在保留的<component>标签中
使用vue:前缀解决 DOM 内模板解析问题
1 | <!-- Vue 2.x --> |
移除的 APIs
按键修饰符
- 不再支持使用数字(按键)作为
v-on修饰符 - 不再支持
config.keyCodes
1 | <!-- Vue 2.x --> |
事件 API
$on, $off, $once 实例方法已被 移除, 组件实例不再实现事件触发接口
过滤器
$filter 过滤被移除
内联模板 Attribute
对 内联模板特性 的支持被移除
- Vue 2.x 使用
inline-template属性将其内容作为模板使用, 而不是作为分发内容
1 | <my-component inline-template> |
$children
$children 实例属性已被 移除
propsData
- Vue 2.x
propsData选项用于在创建 Vue 实例的过程中传入的 prop, 现在已被 移除 - Vue 3.x 使用
createApp的第二个参数传入 prop
1 | // Vue 2.x |
其他变化
片段
- 组件可以包含多个根节点, 需要显示定义 attribute 的位置
1 | <template> |
attribute 强制行为
底层的内部 API 更改, 绝大多数开发人员不会受到影响
自定义指令
- 指令的钩子函数已经被重命名, 以更好地与组件的生命周期保持一致
expression字符串不再作为binding对象的一部分被传入
钩子函数
| Vue 2.x | Vue 3.x |
|---|---|
| created | |
| bind | beforeMount |
| inserted | mounted |
| beforeUpdate | |
| update | |
| componentUpdated | updated |
| beforeUnmount | |
| unbind | unmounted |
Data 选项
- 组件选项
data的声明不再接收纯 JavaScriptObject, 而是接收一个function - 当合并来自
mixin或extend的多个data返回值时, 合并操作现在是浅层次的而非深层次的(只合并根级属性)
mount API
挂载元素时, 被渲染的应用作为子元素插入, 不再替换要挂载的目标元素
- Vue 2.x 当挂载一个具有
template的应用时, 被渲染的内容会替换要挂载的目标元素 - Vue 3.x 被挂载的应用会作为子元素插入, 从而替换目标元素的
innerHTML
1 | <!-- Vue 2.x 替换目标元素 --> |
1 | <!-- Vue 3.x 作为子元素插入到目标元素 --> |
在 prop 的默认函数中不能再访问 this
- 组件接收到的原始 prop 作为参数传递给默认函数
injectAPI 在默认函数中使用
1 | import { inject } from 'vue'; |
Transition class
过渡类名 v-enter 修改为 v-enter-from, 过渡类名 v-leave 修改为 v-leave-from
- v-enter-from
- v-enter-active
- v-enter-to
- v-leave-from
- v-leave-active
- v-leave-to
Transition 作为根节点
当使用 <Transition> 作为根节点的组件从外部被切换时将不再触发过渡效果
TransitionGroup 根元素
<TransitionGroup> 不再默认渲染根元素, 但仍然可以用 tag 属性创建根元素
VNode 生命周期事件
- Vue 2.x 监听组件生命周期的事件名以
hook:前缀开头, 并跟随相应的生命周期钩子的名字
1 | <template> |
- Vue 3.x 前缀改为
vue:开头, 这些事件也可用于 HTML 元素, 和在组件上的用法一样- 绝大多数情况下只需要修改前缀. 生命周期钩子
beforeDestroy和destroyed已经分别被重命名为beforeUnmount和unmounted, 所以相应的事件名也需要更新
- 绝大多数情况下只需要修改前缀. 生命周期钩子
1 | <template> |
侦听数组
当侦听一个数组时, 只有当数组被替换时才会触发回调, 如果需要在数组被改变时触发回调, 必须指定 deep 选项