文章目录
- 前言
- 0.迁移过程
- 1. 安装 Vue 3
- 2. 逐一处理迁移中的警告
- 3. 迁移全局和内部 API
- 4. 迁移 Vue Router 和 Vuex
- 5. 处理其他的不兼容变更
- 1. Vue3特性
- 1. Composition API
- 2. 更好的性能
- 3. 更好的 TypeScript 支持
- 4. 多个根元素
- 5. Suspense 组件
- 6. Teleport 组件
- 7. 全局 API 的改变
- 8. 自定义渲染器 API
- 2.修改清单
- 1.模板指令
- 2. v-model
- 3. key 使用改变
- 4. **v-if 与 v-for 优先级
- 5. v-bind 合并行为
- 6. **v-on.native 移除**:
- 8. 函数式组件
- 9. **异步组件**:
- 10. **emits 选项**:
- 11. **渲染函数**:
- 12. **移除的 APIs**:
- 13. **按键修饰符**:
- 14. **事件 API**:
- 15. **过滤器**:
- 16. **内联模板**:
- 17. **$children**:
- 18. **propsData 选项**:
- 19. **Attribute 强制行为**:
- 20. **自定义指令**:
- 21. **Data 选项**:
- 22. **Mount API 的改变**:
- 23. **Props 的默认函数访问 this**:
- 24. **Transition class 名更改**:
- 25. **Transition 作为根节点**:
- 26. **TransitionGroup 根元素**:
- 27. **VNode 生命周期事件**:
- 28. **Watch 侦听数组**:
- 参考资料
前言
背景:有同学说我上一篇《Vue 2.x 项目升级到 Vue 3详细指南【总结版】》看的太费劲,让我直接整理一篇
Vue2.x 升级到 vue3 的修改清单
,所以整理了此文章。
Vue 3.0 已经发布,很多人可能都在疑惑如何将自己的 Vue 2.x 项目升级到 Vue 3.0。这篇文章将详细地介绍这个过程。它引入了许多新特性和改进,包括更好的性能、更小的包大小、更好的 TypeScript 支持,以及新的 API,如 Composition API。
从 Vue 2.x 升级到 Vue 3 并不是一个简单的任务,因为 Vue 3 引入了一些重大的不兼容变更。这些变更可能会影响你的应用的行为,或者需要你修改你的代码以适应新的 API。
在开始升级之前,我建议你先备份你的项目,或者使用版本控制系统,如Git,以便在需要时可以轻松地回滚到旧版本。此外,你应该确保你的项目的所有依赖项都已经支持 Vue 3,或者至少有可用的替代方案。
现在,让我们开始升级你的 Vue 2.x 项目到 Vue 3 吧!go go
0.迁移过程
1. 安装 Vue 3
首先,你需要安装 Vue 3 到你的项目。你可以通过 npm 或 yarn 来进行安装:
npm install vue@next # 或者 yarn add vue@next
复制
2. 逐一处理迁移中的警告
Vue 3 在兼容性构建中为大部分的有破坏性的改动提供了运行时警告。在你完成初始升级之后,你可以根据运行时控制台中的警告提示逐一处理新代码中的问题。
3. 迁移全局和内部 API
Vue 3 的全局 API 发生了一些改变,如Vue.prototype 被改为 config.globalProperties,Vue.mixin() 现在只适用在应用的根组件,而非全局。这些全局 API 的改变都需要在迁移时被处理和修改。
4. 迁移 Vue Router 和 Vuex
Vue Router 和 Vuex 在 Vue 3 中也有一些改变。你需要安装 vue-router@4 和 vuex@next 并根据相应文档进行迁移。
5. 处理其他的不兼容变更
Vue 3 有一些其他的不兼容变更,如新的生命周期函数名称、更改的事件行为、移除的 filters 等。你需要查阅迁移指南,了解如何处理这些不兼容变更。
1. Vue3特性
在说升级之前 我们先来了解一下。Vue 3 引入了许多新特性和改进,以下是一些主要的亮点:
1. Composition API
这是 Vue 3 的一项主要新特性,它提供了一种新的方式来组织和复用代码。与 Vue 2 的 Options API 相比,Composition API 提供了更好的类型推断,使得 Vue 更易于与 TypeScript 一起使用。
import { ref, computed } from 'vue'; export default { setup() { const count = ref(0); const increment = () => { count.value++ }; const decrement = () => { count.value-- }; const isEven = computed(() => count.value % 2 === 0); return { count, increment, decrement, isEven }; } };
复制
2. 更好的性能
Vue 3 的虚拟 DOM 重写和优化,使得渲染速度比 Vue 2 快约 1.3 到 2 倍。此外,Vue 3 的包大小比 Vue 2 小约 10%。
3. 更好的 TypeScript 支持
Vue 3 的源代码完全用 TypeScript 重写,这使得 Vue 3 与 TypeScript 的集成更加紧密,提供了更好的类型推断和编辑器支持。
4. 多个根元素
vue 3 允许在单文件组件中使用多个根元素,这使得组件的结构更加灵活。
<template> <header>...</header> <main>...</main> <footer>...</footer> </template>
复制
5. Suspense 组件
Vue 3 引入了新的 Suspense
组件,用于处理异步组件的加载状态。这使得你可以在异步组件加载完成之前显示一个加载指示器,或者在加载失败时显示一个错误消息。
<Suspense> <template #default> <AsyncComponent /> </template> <template #fallback> <div>Loading...</div> </template> </Suspense>
复制
6. Teleport 组件
Vue 3 引入了新的 Teleport
组件,用于将子组件渲染到 DOM 树的其他位置。这对于实现模态对话框、通知、弹出菜单等功能非常有用。
<Teleport to="#modal-container"> <div class="modal">...</div> </Teleport>
复制
7. 全局 API 的改变
Vue 3 对全局 API 进行了重大的改变,以使其更加模块化和树摇优化友好。例如,Vue.component
、Vue.directive
等全局 API 在 Vue 3 中被移除,取而代之的是 app.component
、app.directive
等实例方法。
8. 自定义渲染器 API
Vue 3 提供了一个新的自定义渲染器 API,使得你可以创建自己的渲染器,例如用于创建原生移动应用的渲染器。
2.修改清单
我们需要按照以下方式将项目中使用到地方进行修改。以进行适配。
1.模板指令
Vue 3 对多个模板指令进行了更新,包括 v-model
,v-if
/v-for
,v-bind
等。这意味着这些指令的行为可能与 Vue 2 不同,你需要检查你的代码以确保它们与新的行为保持一致。
2. v-model
在 Vue 3 中,v-model
的行为和语法发生了变化。现在,你需要使用 v-model:[argument]="data"
的形式来绑定数据,而不是 Vue 2 中的 v-model="data"
。
<!-- Vue 2 --> <input v-model="message" /> <!-- Vue 3 --> <input v-model:value="message" />
复制
3. key 使用改变
在 Vue 3 中,key
的使用方式发生了变化。现在,v-for
中的 key
是必须的。这意味着你需要在所有的 v-for
指令中添加 key
。
<!-- Vue 2 --> <div v-for="item in items"> {{ item }} </div> <!-- Vue 3 --> <div v-for="item in items" :key="item.id"> {{ item }} </div>
复制
4. **v-if 与 v-for 优先级
在 Vue 3 中,v-if
和 v-for
在同一个元素上的优先级发生了变化。现在,v-if
的优先级高于 v-for
。这意味着如果你在同一个元素上使用了这两个指令,你需要确保它们的使用是正确的。
<!-- Vue 2 --> <div v-for="item in items" v-if="item.isActive"> {{ item }} </div> <!-- Vue 3 --> <div v-for="item in items" :key="item.id"> <div v-if="item.isActive"> {{ item }} </div> </div>
复制
5. v-bind 合并行为
Vue 3 改变了 v-bind
的合并行为。在 Vue 2 中,如果你有多个 v-bind
,它们会被合并。但在 Vue 3 中,后面的 v-bind
会覆盖前面的。
<!-- Vue 2 --> <div v-bind="{ id: 'foo' }" v-bind="{ id: 'bar' }"></div> <!-- id is 'foo' --> <!-- Vue 3 --> <div v-bind="{ id: 'foo' }" v-bind="{ id: 'bar' }"></div> <!-- id is 'bar' -->
复制
6. v-on.native 移除:
Vue 3 移除了 v-on.native
修饰符。你需要更新你的代码,移除所有的 .native
修饰符,并使用新的 emits
选项。
<!-- Vue 2 --> <my-component @click.native="doSomething"></my-component> <!-- Vue 3 --> <my-component @click="doSomething"></my-component>
复制
8. 函数式组件
Vue 3 更改了函数式组件的写法,不再需要 functional
关键词。你需要更新你的函数式组件以适应新的写法。
<!-- Vue 2 --> Vue.component('my-component', { functional: true, // ... }) <!-- Vue 3 --> const MyComponent = (props, { slots }) => { // ... }
复制
9. 异步组件:
Vue 3 改变了异步组件的语法。你需要将你的异步组件语法更新为新的语法。
<!-- Vue 2 --> Vue.component('my-component', () => import('./MyComponent.vue')) <!-- Vue 3 --> const MyComponent = defineAsyncComponent(() => import('./MyComponent.vue'))
复制
10. emits 选项:
Vue 3 添加了全新的 emits
选项,用于定义组件发出的事件。你需要在你的组件中添加 emits
选项。
<!-- Vue 3 --> export default { emits: ['my-event'], methods: { doSomething() { this.$emit('my-event') } } }
复制
11. 渲染函数:
Vue 3 的渲染函数 API 有所改变。你需要更新你的渲染函数以适应新的 API。
<!-- Vue 2 --> Vue.component('my-component', { render: function (createElement) { return createElement('div', this.$slots.default) } }) <!-- Vue 3 --> const MyComponent = { render() { return h('div', this.$slots.default()) } }
复制
12. 移除的 APIs:
Vue 3 移除了一些不再需要的 APIs,例如 Vue.set
,Vue.delete
和 Vue.observable
。这些API在Vue.js 2.x中用于添加响应式属性到对象或删除属性,Vue 3中的响应式系统使用 Proxy,所以这些API不再需要。
// Vue 2 Vue.set(object, propertyName, value); Vue.delete(object, propertyName); Vue.observable(object); // Vue 3 // 整个对象都是响应式的,不需要特定的API
复制
13. 按键修饰符:
Vue 3 不再支持按键修饰符的别名,例如 @keyup.enter
,@keyup.space
等。你需要将这些修饰符替换为它们的键码。
<!-- Vue 2 --> <input @keyup.enter="submit"> <!-- Vue 3 --> <input @keyup.13="submit">
复制
14. 事件 API:
Vue 3 的事件 API 有所改变,例如 $on
,$off
和 $once
已被移除。你需要使用新的事件 API。
// Vue 2 this.$on('event', handler); this.$off('event', handler); this.$once('event', handler); // Vue 3 // 使用事件发射器如mitt或tiny-emitter
复制
15. 过滤器:
Vue 3 不再支持过滤器。你需要将过滤器替换为计算属性或者方法。
<!-- Vue 2 --> {{ message | filterA | filterB }} <!-- Vue 3 --> {{ filterB(filterA(message)) }}
复制
16. 内联模板:
Vue 3 不再支持内联模板。你需要将内联模板替换为 render
函数或者 template
。
<!-- Vue 2 --> <my-component inline-template> <div>{{ message }}</div> </my-component> <!-- Vue 3 --> <my-component> <template #default="{ message }"> <div>{{ message }}</div> </template> </my-component>
复制
17. $children:
Vue 3 不再支持 $children
。你需要找到其他方式来访问子组件。要访问子组件,可以使用 ref
和 provide/inject
。
<!-- Vue 2 --> this.$children; <!-- Vue 3 --> // 使用 ref 或 provide/inject 访问子组件
复制
18. propsData 选项:
Vue 3 不再支持 propsData
选项。你需要在创建组件实例时直接传递 props
。
// Vue 2 new Vue({ propsData: { prop: value, }, }); // Vue 3 createApp({ props: { prop: value, }, });
复制
19. Attribute 强制行为:
Vue 3 现在默认将未声明的 attribute 视为 DOM attribute。如果你需要强制 attribute 来响应化,你需要使用 v-bind
。
<!-- Vue 2 --> <my-component my-attr="value" /> <!-- Vue 3 --> <my-component v-bind="{ 'my-attr': 'value' }" />
复制
20. 自定义指令:
Vue 3 的自定义指令 API 有所改变。你需要更新你的自定义指令以适应新的 API。
// Vue 2 Vue.directive('my-directive', { bind(el, binding, vnode, oldVnode) { /* ... */ }, update(el, binding, vnode, oldVnode) { /* ... */ }, }); // Vue 3 const myDirective = { beforeMount(el, binding, vnode, prevVnode) { /* ... */ }, updated(el, binding, vnode, prevVnode) { /* ... */ }, };
复制
21. Data 选项:
Vue 3 的 data
选项必须是一个函数。你需要将所有的 data
选项转换为函数。
// Vue 2 new Vue({ data: { message: 'Hello Vue!', }, }); // Vue 3 createApp({ data() { return { message: 'Hello Vue!', }; }, });
复制
22. Mount API 的改变:
Vue 3 的 mount
API 有所改变。你需要更新你的 mount
调用以适应新的 API。
// Vue 2 new Vue({ /* options */ }).$mount('#app'); // Vue 3 createApp({ /* options */ }).mount('#app');
复制
23. Props 的默认函数访问 this:
Vue 3 不再允许在 props 的默认函数中访问 this
。你需要找到其他方式来获取需要的数据。
// Vue 2 props: { prop: { default: function () { return this.someData; }, }, }; // Vue 3 props: { prop: { default() { // "this" 是 undefined }, }, };
复制
24. Transition class 名更改:
Vue 3 更改了 transition 的 class 名称,为了与 CSS 动画一致,v-enter
改为了 v-enter-from
,v-leave
改为了 v-leave-from
。
/* Vue 2 */ .fade-enter, .fade-leave-to { opacity: 0; } /* Vue 3 */ .fade-enter-from, .fade-leave-to { opacity: 0; }
复制
25. Transition 作为根节点:
Vue 3 不再允许 transition 作为根节点。你需要确保你的组件有一个非 transition 的根节点。
<!-- Vue 2 --> <transition> <div>...</div> </transition> <!-- Vue 3 --> <!-- transition 不能作为根节点 --> <div> <transition> <div>...</div> </transition> </div>
复制
26. TransitionGroup 根元素:
Vue 3 的 TransitionGroup
不再渲染一个默认的根元素。你需要手动添加一个根元素。
<!-- Vue 2 --> <transition-group> <div v-for="item in items" :key="item.id">{{ item }}</div> </transition-group> <!-- Vue 3 --> <transition-group> <div> <div v-for="item in items" :key="item.id">{{ item }}</div> </div> </transition-group>
复制
27. VNode 生命周期事件:
Vue 3 的 VNode 生命周期事件有所改变。你需要更新你的代码以适应新的事件。
// Vue 2 vnode.context.$on('hook:updated', handler); // Vue 3 onUpdated(handler);
复制
28. Watch 侦听数组:
Vue 3 的 watch
对于数组的行为有所改变。你需要更新你的 watch
调用以适应新的行为。
// Vue 2 watch(() => [...array], handler); // Vue 3 watch(() => array, handler, { deep: true });
复制
参考资料
-
Vue 3 Migration Guide - Vue 官方提供的迁移指南,详细介绍了从 Vue 2 到 Vue 3 的各种改变和升级策略。
-
Vue 3 Upgrade Guide - 这篇博客文章详细介绍了 Vue 2 到 Vue 3 的升级过程,包括实践技巧和遇到的问题。