https://v3-migration.vuejs.org/zh/

用于迁移的构建版本

  • @vue/compat (即“迁移构建版本”) 是一个 Vue 3 的构建版本,提供了可配置的兼容 Vue 2 的行为。
  • 使用在 Vue 3 中发生改变或被废弃的特性时会抛出运行时警告。一个特性的兼容性也可以基于单个组件进行开启或禁用。
  • 该迁移构建版本可以被用于服务端渲染,但是迁移一个自定义的服务端渲染配置还有很多工作要做。大致的思路是将 vue-server-renderer 替换为 @vue/server-renderer。Vue 3 不再提供一个包渲染器,且我们推荐使用 Vite 以支持 Vue 3 服务端渲染。如果你正在使用 Nuxt.js,可以尝试 Nuxt Bridge,一个 Nuxt.js 2 到 3 的兼容层。对于复杂、生产环境的项目来说,可能更好还是等待一下 Nuxt 3
    • 注释:vue-server-renderer 服务端渲染工具,它作用是创建一个渲染器,它可以将Vue实例渲染成HTML字符串。
    • 注释:@vue/server-renderer 是一个客户端渲染包,Vue 3 不再提供一个包渲染器,这句话可能是说没有专门的服务端渲染包了。
  • 请注意迁移构建版本旨在覆盖在文档中公开记载的 Vue 2 API 和行为。
  • 升级流程
    • 如果你仍然使用废弃的具名/作用域插槽语法,请先将其更新至 (2.6 已经支持的) 最新的语法。
      • 注释:v-slot 指令自 Vue 2.6.0 起被引入,提供更好的支持 slot 和 slot-scope attribute 的 API 替代方案。
    • 尽可能升级工具
      • 如果使用了自定义的 webpack 设置:将 vue-loader 升级至 ^16.0.0
      • 如果使用了 vue-cli:通过 vue upgrade 升级到最新的 @vue/cli-service。
      • (替代方案) 迁移至 Vite + vite-plugin-vue2
    • 在 package.json 里,将 vue 更新到 3.1,安装相同版本的 @vue/compat。且如果存在 vue-template-compiler 的话,将其替换为 @vue/compiler-sfc。
      • 注释:vue-template-compiler是Vue.js的模板编译器,它将Vue模板语法转换成渲染函数。
    • 在构建设置中,为 vue 设置别名 @vue/compat,且通过 Vue 编译器选项开启兼容模式。
      • 注释:通过 compilerOptions.compatConfig 配置,参考文档
    • 如果使用了 TypeScript,你还需要修改 vue 的类型,通过添加一个 *.d.ts 暴露其 (在 Vue 3 中已经不再展示) 默认导出。
      • 注释:因为之前设置了别名,所以 vue 的实际类型发生了改变
declare module 'vue' {
  import { CompatVue } from '@vue/runtime-dom'
  const Vue: CompatVue
  export default Vue
  export * from '@vue/runtime-dom'
  const { configureCompat } = Vue
  export { configureCompat }
}
  • 注释:接上面
    • 你可能会同时从命令行和浏览器控制台看到很多警告。这里提供一些一般化的小建议:
      • 可以在浏览器控制台里过滤特定的警告。建议通过使用过滤器,使自己每次专注修复同一种问题。你也可以使用类似 -GLOBAL_MOUNT 的否定式过滤器。
      • 你可以通过兼容性配置关闭对特定的废弃内容的处理
      • 如果你使用了 vue-router,请注意在升级至 vue-router v4 之前,<transition> 和 <keep-alive> 无法和 <router-view> 一起工作
    • 升级 <transition> 类名。这是唯一没有运行时警告的特性。你可以在整个项目范围内做一次 .-enter 和 .-leave CSS 类名的搜索
      • 注释:过渡类名 v-enter 修改为 v-enter-from、过渡类名 v-leave 修改为 v-leave-from
    • 更新应用的入口以使用新的全局挂载 API
      • 注释:通过 createapp 创建应用实例,通过 应用实例.mount 挂载
      • 注释:应用实例会暴露一个 .config 对象允许我们配置一些应用级的选项。应用实例还提供了一些方法来注册应用范围内可用的资源
    • 将 vuex 升级至 v4
      • 注释:略
    • 将 vue-router 升级至 v4。如果你还使用了 vuex-router-sync,可以同时将其替换为一个 store getter。
      • 注释:略
      • 注释:vuex-router-sync 能够将 vue-router 当前路由的状态同步到 vuex 中,从而使路由信息具有响应式
      • 升级过后,同 <router-view> 一起使用 <transition> 和 <keep-alive> 就要求使用新的基于作用域插槽的语法。
        • 注释:transition 和 keep-alive 现在必须通过 v-slot API 在 RouterView 内部使用
<router-view v-slot="{ Component }">
  <transition>
    <keep-alive>
      <component :is="Component" />
    </keep-alive>
  </transition>
</router-view>
  • 注释:接上面
    • 注意有些特性在 Vue 2 和 Vue 3 之间存在行为冲突——例如渲染函数 API,或函数式组件 vs. 异步组件的改变。为了迁移到 Vue 3 API 而不影响到应用的其它部分,你可以通过 compatConfig 选项对单个组件选择性启用 Vue 3 的行为。
export default {
  compatConfig: {
    MODE: 3, // 只为这个组件选择性启用 Vue 3 行为
    FEATURE_ID_A: true // 也可以在组件级别开启某些特性
  }
  // ...
}
  • 兼容性特性可以进行单独禁用:或者整个应用默认为 Vue 3 的行为,仅开启某些兼容性特性:
import { configureCompat } from 'vue'

// 所有 Vue 3 的默认行为,并开启某些兼容性特性
configureCompat({
  MODE: 3,
  FEATURE_ID_A: true,
  FEATURE_ID_B: true
})
  • 以 COMPILER_ 开头的特性是针对编译器的:如果你正在使用完整构建版本 (含浏览器内编译器),它们可以在运行时中被配置。然而如果使用构建设置,它们必须换为通过在构建配置中的 compilerOptions 进行配置
  • 不兼容 (只有警告)
    • 注释:这些差异和 vue2 是没有平替方案的需要修改代码实现,虽然 @vue/compat 提供以下配置项使其行为和 vue2 相同,但是应该对它们进行修正并逐步关闭配置项,从而平滑的从vue2过度到vue3
    • GLOBAL_MOUNT_CONTAINER 被挂载的应用不会替换被挂载到的元素
    • CONFIG_DEVTOOLS 生产环境开发者工具现在是一个构建时的开关
      • 注释:在构建工具中通过配置决定以下功能
        • VUE_OPTIONS_API 启用/禁用选项API支持,默认值:true
        • VUE_PROD_DEVTOOLS 在生产环境中启用/禁用 devtools 支持,默认值:false
      • 注释:各个打包工具具体配置方法,参考
    • COMPILER_V_IF_V_FOR_PRECEDENCE v-if 和 v-for 用在相同的元素上时的处理顺序发生了改变
    • COMPILER_V_IF_SAME_KEY v-if 分支不能再拥有相同的 key
    • COMPILER_V_FOR_TEMPLATE_KEY_PLACEMENT <template v-for> key 现在应该被放在 <template> 上
    • COMPILER_SFC_FUNCTIONAL 单文件组件中不再支持 <template functional>
      • 注释:2.x 中函数式组件带来的性能提升在 3.x 中已经可以忽略不计,因此我们建议只使用有状态的组件
      • 注释:升级参考
      • 注释:在 Vue 3 中,所有的函数式组件都是用普通函数创建的。
// vue2
export default {
  functional: true,
  props: ['level'],
  render(h, { props, data, children }) {
    return h(`h${props.level}`, data, children)
  }
}

// vue3
import { h } from 'vue'

const DynamicHeading = (props, context) => {
  return h(`h${props.level}`, context.attrs, context.slots)
}

DynamicHeading.props = ['level']

export default DynamicHeading
  • 部分兼容且附带注意事项
    • CONFIG_IGNORED_ELEMENTS config.ignoredElements 现在改为了 config.compilerOptions.isCustomElement (只在浏览器编译器构建版本中)。如果使用了构建设置,isCustomElement 必须通过构建配置传入。
      • 注释:vue2中 config.ignoredElements 用于定义须使 Vue 忽略在 Vue 之外的自定义元素
      • 注释:在 Vue 3 中,元素是否是组件的检查已转移到模板编译阶段,因此只有在使用运行时编译器时此配置选项才会生效
    • COMPILER_INLINE_TEMPLATE inline-template 被移除 (兼容模式只在浏览器编译器构建版本中支持)
    • PROPS_DEFAULT_THIS prop 的默认工厂方法不再可以访问 this (在兼容模式下,this 不是一个真实的实例——它只暴露 prop、$options 和注入)
      • 注释:vue3中 组件接收到的原始 prop 将作为参数传递给默认函数,inject API 可以在默认函数中使用。
    • INSTANCE_DESTROY $destroy 实例方法被移除 (在兼容模式下,只在根实例下支持)
    • GLOBAL_PRIVATE_UTIL Vue.util 是私有的,且不再可用
    • CONFIG_PRODUCTION_TIP 不再需要 config.productionTip
      • 注释:vue2中 config.productionTip 用于配置,vue 在启动时生成生产提示
      • 注释:在 Vue 3.x 中,“使用生产版本”提示仅在使用“dev + full build”(包含运行时编译器并有警告的构建版本) 时才会显示。
    • CONFIG_SILENT config.silent 被移除
      • 注释:vue2中 用于配置取消 Vue 所有的日志与警告
  • 仅兼容 (无告警)
    • TRANSITION_CLASSES 过渡动画的进入/离开的 class 发生了变化
  • 完全兼容
    • 注释:提供了直接的平替方案,只需要根据引导替换对应代码就行。
    • GLOBAL_MOUNT new Vue() -> createApp
    • GLOBAL_EXTEND Vue.extend 被移除 (使用 defineComponent 或 extends 选项)
      • 注释:在 Vue 2.x 中,Vue.extend 曾经被用于创建一个基于 Vue 构造函数的“子类”,其参数应为一个包含组件选项的对象。在 Vue 3.x 中,我们已经没有组件构造器的概念了。应该始终使用 createApp 这个全局 API 来挂载组件
      • 注释:在 Vue 2 中,Vue.extend 也被用来为组件选项提供 TypeScript 类型推断。在 Vue 3 中,为了达到相同的目的,defineComponent 全局 API 可以用来作为 Vue.extend 的替代方案
    • GLOBAL_PROTOTYPE Vue.prototype -> app.config.globalProperties
      • 注释:在 Vue 3 中与之对应的是 config.globalProperties。这些 property 将被复制到应用中,作为实例化组件的一部分。
      • 注释:使用 app.provide(),也应考虑作为 globalProperties 的替代品
    • GLOBAL_SET Vue.set 被移除 (不再需要)
    • GLOBAL_DELETE Vue.delete 被移除 (不再需要)
    • GLOBAL_OBSERVABLE Vue.observable 被移除 (使用 reactive)
    • CONFIG_KEY_CODES config.keyCodes 被移除
      • 注释:vue3 中现在建议对任何要用作修饰符的键使用 kebab-cased (短横线) 名称
      • 注释:同时支持大小写
      • 注释:w3c 使用 KeyboardEvent.code 规范统一了虚拟按键和实体按键的返回,所以不再需要通过 config.keyCodes 去映射
    • CONFIG_WHITESPACE 在 Vue 3 中空格默认为 "condense"
      • 注释:condense 合并连续的空格为1个
      • 注释:vue2中会保留所有的空格
    • INSTANCE_SET vm.$set 被移除 (不再需要)
    • INSTANCE_DELETE vm.$delete 被移除 (不再需要)
    • INSTANCE_EVENT_EMITTER vm.$on、vm.$off、vm.$once 被移除
      • 注释:事件总线模式可以被替换为使用外部的、实现了事件触发器接口的库,例如 mitttiny-emitter
      • 注释:Prop 逐级透传也可以通过重构以使用插槽来避免。如果一个中间组件不需要某些 prop,那么表明它可能存在关注点分离的问题。在该类组件中使用 slot 可以允许父节点直接为它创建内容,因此 prop 可以被直接传递而不需要中间组件的参与。
      • 注释:静态的事件监听器可以通过 prop 的形式传递给 createApp 以添加到根组件中。
createApp(App, {
  // 监听 'expand' 事件
  onExpand() {
    console.log('expand')
  }
})
  • 注释:接上面
    • INSTANCE_EVENT_HOOKS 实例不再抛出 hook:x 事件
      • 注释:在 Vue 2 中,我们可以通过事件来监听组件生命周期中的关键阶段。这些事件名都是以 hook: 前缀开头,并跟随相应的生命周期钩子的名字。
      • 注释:在 Vue 3 中,这个前缀已被更改为 vue:。额外地,这些事件现在也可用于 HTML 元素,和在组件上的用法一样。
      • 注释:生命周期钩子 beforeDestroy 和 destroyed 已经分别被重命名为 beforeUnmount 和 unmounted,所以相应的事件名也需要更新。
// vue2
<template>
  <child-component @hook:updated="onUpdated">
</template>

// vue3
<template>
  <child-component @vue:updated="onUpdated">
</template>
  • 注释:接上面
    • INSTANCE_CHILDREN vm.$children 被移除
      • 注释:在 3.x 中,$children property 已被移除,且不再支持。如果你需要访问子组件实例,我们建议使用模板引用。
      • 注释:应该注意的是,ref 数组并不保证与源数组相同的顺序
      • 注释:ref attribute 还可以绑定为一个函数,会在每次组件更新时都被调用。该函数会收到元素引用作为其第一个参数
      • 注释:使用了 <script setup> 的组件是默认私有的:一个父组件无法访问到一个使用了 <script setup> 的子组件中的任何东西,除非子组件在其中通过 defineExpose 宏显式暴露
    • INSTANCE_LISTENERS vm.$listeners 被移除
      • 注释:$listeners 对象在 Vue 3 中已被移除。事件监听器现在是 $attrs 的一部分
    • INSTANCE_SCOPED_SLOTS vm.$scopedSlots 被移除;vm.$slots 现在暴露函数
// 2.x 语法
h(LayoutComponent, [
  h('div', { slot: 'header' }, this.header),
  h('div', { slot: 'content' }, this.content)
])

this.$scopedSlots.header

// 3.x Syntax
h(LayoutComponent, {}, {
  header: () => h('div', this.header),
  content: () => h('div', this.content)
})

this.$slots.header()
  • 注释:接上面
    • INSTANCE_ATTRS_CLASS_STYLE $attrs 现在包含了 class 和 style
      • 注释:vue2中使用 inheritAttrs: false 时$attrs 中的 attribute 将不再被自动添加到根元素中,而是由开发者决定在哪添加,但是 class 和 style 不属于 $attrs,它们仍然会被应用到组件的根元素中
    • OPTIONS_DATA_FN data 在所有情况下都必须是一个函数
    • OPTIONS_DATA_MERGE 来自 mixin 或扩展的 data 现在都是浅合并
    • OPTIONS_BEFORE_DESTROY beforeDestroy -> beforeUnmount
    • OPTIONS_DESTROYED destroyed -> unmounted
    • WATCH_ARRAY 对于一个数组的操作,侦听无法被触发了,除非使用了深度侦听
      • 注释:watch option 侦听函数的值也可以是一个方法名称的字符串 (通过 methods 声明)
      • 注释:可以传入回调数组,它们将会被逐一调用
      • 注释:watch option 对于对象的侦听都是浅层的。
      • 注释:watch compositionApi 监听响应对象时默认是深层的,监听 getter 时是浅层的
      • 注释:this.$watch 允许监听一个 getter,但是 watch option 无法实现。
    • V_ON_KEYCODE_MODIFIER v-on 不再支持 keyCode 修饰符
    • CUSTOM_DIR 自定义指令钩子命名变化
      • 注释:指令的钩子函数已经被重命名,以更好地与组件的生命周期保持一致。
      • 注释:expression 字符串不再作为 binding 对象的一部分被传入
        • vue2 中 expression 包含了绑定到指令上的表达式字符串
      • 注释:vue3 中的钩子函数
        • created - 新增!在元素的 attribute 或事件监听器被应用之前调用
        • bind → beforeMount
        • inserted → mounted
        • beforeUpdate:新增!在元素本身被更新之前调用,与组件的生命周期钩子十分相似。
        • update → 移除!该钩子与 updated 有太多相似之处,因此它是多余的。请改用 updated
        • componentUpdated → updated
        • beforeUnmount:新增!与组件的生命周期钩子类似,它将在元素被卸载之前调用。
        • unbind -> unmounted
      • 注释:在 Vue 2 中,必须通过 vnode 参数访问组件实例const vm = vnode.context,在 Vue 3 中,实例现在是 binding 参数的一部分const vm = binding.instance
      • 注释:有了片段的支持,组件可能会有多个根节点。当被应用于多根组件时,自定义指令将被忽略,并将抛出警告。
    • ATTR_FALSE_VALUE attribute 的绑定值为布尔值 false 时不再将其移除
      • 注释:若要移除 attribute,应该使用 null 或者 undefined,不设置值被保留为attr=''
      • 注释:在运行时 vue2 会对不同的 attribute 类型进行特殊处理
        • 对于某些 attribute/元素对,Vue 始终使用相应的 IDL attribute (property):比如 <input>,<select>,<progress> 中的 value,等等
          • IDL attribute是接口定义语言(Interface Definition Language)中的属性,也被称为IDL标记。IDL属性用于描述对象的数据成员以及这些成员如何与对象的行为相关联。在IDL中,属性被声明为对象接口的一部分,并指定了属性的名称、类型、访问权限等特性。
        • 对于“布尔 attribute”和 xlinks,如果它们是 falsy (undefined,null 或 false) 的,Vue 会移除它们,否则会加上
          • XLink允许在XML文档中插入元素以创建和描述资源间的链接,关联元数据,以及链接外部文档。XLink比HTML中的链接能力更强,提供先进的行为特征使得超链接更加灵活。
        • 对于“枚举 attribute” (目前来说包括 contenteditable、draggable 和 spellcheck),Vue 会尝试将它们强制转换为字符串
          • contenteditable是一个HTML属性,用于指定元素内容是否可编辑
          • draggable 拖拽
          • spellcheck 用于控制用户在输入内容时是否进行拼写检查
        • 对于其他 attribute,我们将移除 falsy 的值 (undefined,null,或 false),其他值按原样设置
      • 注释:在 vue3 中统一了 布尔 attribute、枚举 attribute 和 其他 attribute,绑定值为布尔值 false 时不再将其移除
    • ATTR_ENUMERATED_COERCION 不再特殊处理枚举类型 attribute
    • TRANSITION_GROUP_ROOT <transition-group> 不再默认渲染一个根元素,但仍然可以用 tag attribute 创建根元素。
    • COMPONENT_ASYNC 异步组件 API 改变 (现在需要 defineAsyncComponent)
      • 注释:vue2 异步组件是通过将组件定义为返回 Promise 的函数来创建的,或者,带有选项的的组件语法{component: () => import('./Modal.vue'), delay: 200, timeout: 3000, error: ErrorComponent, loading: LoadingComponent}
      • 注释:在 Vue 3 中,由于函数式组件被定义为纯函数,因此异步组件需要通过将其包裹在新的 defineAsyncComponent 助手方法中来显式地定义。
        • defineAsyncComponent 的参数和 vue2 异步组件相同
        • component 选项现在被重命名为 loader,loader 函数不再接收 resolve 和 reject 参数,且必须始终返回 Promise
          • vue2.0中允许const oldAsyncComponent = (resolve, reject) => {}
    • COMPONENT_FUNCTIONAL 函数式组件 API 改变 (现在必须只是一个普通函数)
    • COMPONENT_V_MODEL 组件的 v-model 修改
      • 用于自定义组件时,v-model prop 和事件默认名称已更改:value -> modelValue、input -> update:modelValue
      • v-bind 的 .sync 修饰符和组件的 model 选项已移除,可在 v-model 上加一个参数代替
      • 现在若需要更改 model 的名称,现在我们可以为 v-model 传递一个参数,以作为组件内 model 选项的替代<ChildComponent v-model:title="pageTitle" />
      • 除了像 .trim 这样的 2.x 硬编码的 v-model 修饰符外,现在 3.x 还支持自定义修饰符
        • .trim 输入首尾空格过滤
        • 自定义修饰符会多接收到一个名为 参数+'Modifiers' 的 prop,它是一个对象,里面包含了被使用的 修饰符:true 键值对
    • RENDER_FUNCTION 渲染函数 API 更改
      • 注释:这个兼容性可能还包括 vnode 的兼容
      • 注释:h 现在是全局导入,而不是作为参数传递给渲染函数
      • 注释:更改渲染函数参数,使其在有状态组件和函数组件的表现更加一致
        • 渲染函数 render 不再接收参数 h
      • 注释:在 2.x 中,注册一个组件后,把组件名作为字符串传递给渲染函数的第一个参数,它可以正常地工作return h('button-counter')。在 3.x 中,由于 VNode 是上下文无关的,不能再用字符串 ID 隐式查找已注册组件。取而代之的是,需要使用一个导入的 resolveComponent 方法h(resolveComponent('button-counter'))
      • 注释:渲染函数 API 更改 RFC
        • In addition, you can hook into the vnode lifecycle using reserved onVnodeXXX prefixed hooks:
        • 使用保留的 onVnodeXXX 前缀钩子来钩入预定义的 vdom 生命周期
        • These hooks are also how custom directives are built on top of. Since they start with on, they can also be declared with v-on in templates:
        • 这些钩子也是自定义指令的构建方式。由于它们以on开头,因此也可以在模板中使用v-on声明
        • Due to the flat structure, this.$attrs inside a component now contains any raw props that are not explicitly declared by the component, including class, style, onXXX listeners and vnodeXXX hooks. This makes it much easier to write wrapper components - simply pass this.$attrs down with v-bind="$attrs".
        • 由于采用了扁平结构,组件内部的this.attrs现在包含任何未被组件显式声明的原始props,包括class、style、onXXX监听器和vnodeXXX钩子。这使得编写包装组件变得更加容易——只需使用v−bind="attrs"将this.$attrs传递下去即可。
        • Same for looking up directives. Instead, we need to use an imported API
        • 使用const fooDir = resolveDirective('foo') 导入自定义指令,使用withDirectives(h(comp), [fooDir, this.x])使用指令
      • 注释:VNode 现在有一个扁平的 prop 结构
        • 在 2.x 中,domProps 包含 VNode prop 中的嵌套列表:
        • 在 3.x 中,整个 VNode prop 的结构都是扁平的。使用上面的例子,来看看它现在的样子。
// 2.x
{
  staticClass: 'button',
  class: { 'is-outlined': isOutlined },
  staticStyle: { color: '#34495E' },
  style: { backgroundColor: buttonColor },
  attrs: { id: 'submit' },
  domProps: { innerHTML: '' },
  on: { click: submitForm },
  key: 'submit-button'
}

// 3.x 语法
{
  class: ['button', { 'is-outlined': isOutlined }],
  style: [{ color: '#34495E' }, { backgroundColor: buttonColor }],
  id: 'submit',
  innerHTML: '',
  onClick: submitForm,
  key: 'submit-button'
}
  • 注释:接上面
    • FILTERS 过滤器被移除 (该选项只会影响运行时的过滤器 API)
      • 如果在应用中全局注册了过滤器,那么在每个组件中用计算属性或方法调用来替换它可能就没那么方便了。取而代之的是,你可以通过全局属性以让它能够被所有组件使用到:app.config.globalProperties.$filters = {}
    • COMPILER_IS_ON_ELEMENT is 的使用现在被严格限制在 <component> 上
      • 因为 w3c 自定义元素规范提供了一种将自定义元素作为自定义内置元素的方法<button is="plastic-button">点击我!</button>
      • 使用 vue: 前缀来解决 DOM 内模板解析问题<tr is="vue:blog-post-row"></tr>
    • COMPILER_V_BIND_SYNC v-bind.sync 被替换为带参数的 v-model
    • COMPILER_V_BIND_PROP v-bind.prop 修饰符被移除
      • vue2中 .prop - 作为一个 DOM property 绑定而不是作为 attribute 绑定。
      • property 是 dom 的属性,attribute 是 html 标签上绑定的属性,vnode中会自动把attribute 转为property
    • COMPILER_V_BIND_OBJECT_ORDER v-bind="object" 现在是顺序敏感的
      • 在 2.x 中,如果一个元素同时定义了 v-bind="object" 和一个相同的独立 attribute,那么这个独立 attribute 总是会覆盖 object 中的绑定
      • 在 3.x 中,如果一个元素同时定义了 v-bind="object" 和一个相同的独立 attribute,那么绑定的声明顺序将决定它们如何被合并。
    • COMPILER_V_ON_NATIVE v-on.native 修饰符被移除
      • vue3中对于子组件中未被定义为组件触发的所有事件监听器,Vue 现在将把它们作为原生事件监听器添加到子组件的根元素中 (除非在子组件的选项中设置了 inheritAttrs: false)。
    • COMPILER_V_FOR_REF v-for 中的 ref (编译器支持))
    • COMPILER_NATIVE_TEMPLATE 没有特殊指令的 <template> 现在会被渲染为原生元素
      • 在 vue3 中没有任何特殊指令的 template 中的元素不会被渲染
    • COMPILER_FILTERS 过滤器 (编译器支持)
posted on 2023-12-11 16:21  噬蛇之牙  阅读(557)  评论(0编辑  收藏  举报