Vue2 迁移到 Vue3

一.《Vue 3 迁移指南》参考文档:https://v3-migration.vuejs.org/zh/

二.Vue 3 中需要关注的一些新特性。
1. 组合式 API*;
2. 单文件组件中的组合式 API 语法糖 (<script setup>)*;
3. Teleport 组件;
4. Fragments 片段;
5. Emits 组件选项**;
6. 来自 @vue/runtime-core 的 createRenderer API 用来创建自定义渲染函数;
7. 单文件组件中的状态驱动的 CSS 变量 (<style> 中的 v-bind)*;
8. SFC <style scoped> 新增全局规则和针对插槽内容的规则;
9. Suspense 实验性。

* 现在也支持在 Vue 2.7 中使用,
** Vue 2.7 中支持,但仅用于类型推断。

三.新的框架级别推荐。
Vue 3 的支持库进行了重大更新。以下是新的默认建议的摘要:
1. 新版本的 Router, Devtools & test utils 来支持 Vue 3;
2. 构建工具链: Vue CLI -> Vite【https://cn.vitejs.dev/】
3. 状态管理: Vuex -> Pinia【https://pinia.vuejs.org/zh/index.html】
4. IDE 支持: Vetur -> Volar【https://marketplace.visualstudio.com/items?itemName=vue.volar】
5. 新的 TypeScript 命令行工具: vue-tsc【https://github.com/vuejs/language-tools/tree/master/vue-language-tools/vue-tsc】
6. 静态网站生成: VuePress -> VitePress【https://vitepress.dev/】
7. JSX: @vue/babel-preset-jsx -> @vue/babel-plugin-jsx【https://github.com/vuejs/babel-plugin-jsx】


四.用于迁移的构建版本。
@vue/compat (即“迁移构建版本”) 是一个 Vue 3 的构建版本,提供了可配置的兼容 Vue 2 的行为。

该构建版本默认运行在 Vue 2 的模式下——大部分公有 API 的行为和 Vue 2 一致,仅有一小部分例外。使用在 Vue 3 中发生改变或被废弃的特性时会抛出运行时警告。一个特性的兼容性也可以基于单个组件进行开启或禁用。

预期用例:
1. 将一个 Vue 2 应用升级为 Vue 3 (存在限制)。
2. 迁移一个库以支持 Vue 3。
3. 对于尚未尝试 Vue 3 的资深 Vue 2 开发者来说,迁移构建版本可以用来代替 Vue 3 以更好地学习版本之间的差异。

五.非兼容性改变。
参考文档:https://v3-migration.vuejs.org/zh/breaking-changes/

1. 全局API。
(1). 全局 Vue API 更改为使用应用程序实例。
Vue 2.x 有许多全局 API 和配置,它们可以全局改变 Vue 的行为。例如,要注册全局组件,可以使用 Vue.component API,虽然这种声明方式很方便,但它也会导致一些问题。从技术上讲,Vue 2 没有“app”的概念,Vue 2定义的应用只是通过 new Vue() 创建的根 Vue 实例。从同一个 Vue 构造函数创建的每个根实例共享相同的全局配置。

createApp是 Vue 3 中的 一个 新概念,调用 createApp 返回一个应用实例。
    import { createApp } from 'vue'
    const app = createApp({})

如果使用的是 Vue3 的 CDN 构建版本,那么 createApp 将通过全局的 Vue 对象暴露。
    const { createApp } = Vue
    const app = createApp({})

(2). 全局和内部 API 都经过了重构,现已支持 TreeShaking (摇树优化)。
由于之前的 Vue2 版本中的代码编写方式,如 Vue.nextTick() 这样的全局 API 是不支持 tree-shake 的,不管它们实际上是否被使用了,都会被包含在最终的打包产物中。

在 Vue 3 中,全局和内部 API 都经过了重构,并考虑到了 tree-shaking 的支持。因此,对于 ES 模块构建版本来说,全局 API 现在通过具名导出进行访问。例如:
    import { nextTick } from 'vue'
    nextTick(() => {
        // 一些和 DOM 有关的东西
    })

2. 模板指令。
(1). v-model 指令在组件上的使用已经被重新设计,替换掉了 v-bind.sync。

用于自定义组件时,v-model prop 和事件默认名称已更改:
prop:value -> modelValue;
事件:input -> update:modelValue;

v-bind 的 .sync 修饰符和组件的 model 选项已移除,可在 v-model 上加一个参数.lazy代替。

现在可以在同一个组件上使用多个 v-model 绑定,还可以自定义 v-model 修饰符。

(2). 在<template v-for> 和没有 v-for 的节点身上使用 key 发生了变化。

对于 v-if/v-else/v-else-if 的各分支项 key 将不再是必须的,因为现在 Vue 会自动生成唯一的 key。

如果你手动提供 key,那么每个分支必须使用唯一的 key。你将不再能通过故意使用相同的 key 来强制重用分支。

<template v-for> 的 key 应该设置在 <template> 标签上 (而不是设置在它的子节点上)。

(3). v-if 和 v-for 在同一个元素身上使用时的优先级发生了变化。

Vue2.x 版本中,在一个元素上同时使用 v-if 和 v-for 时,v-for 会优先作用。

Vue3.x 版本中 v-if 总是优先于 v-for 生效。

(4). v-bind="object" 现在是顺序敏感的。
在 Vue2.x 中,如果一个元素同时定义了 v-bind="object" 和一个相同的独立 attribute,那么这个独立 attribute 总是会覆盖 object 中的绑定。
示例:
    <!-- 模板 -->
    <div id="red" v-bind="{ id: 'blue' }"></div>
    <!-- 结果 -->
    <div id="red"></div>

在 Vue3.x 中,如果一个元素同时定义了 v-bind="object" 和一个相同的独立 attribute,那么绑定的声明顺序将决定它们如何被合并【后面覆盖前面】。

(5). v-on:event.native 事件修饰符已经被移除。

Vue3中 新增的 emits 选项允许子组件定义真正会被触发的事件。


3. 组件。
(1). 函数式组件只能通过纯函数进行创建。

Vue2.x 中函数式组件带来的性能提升在 Vue3.x中已经可以忽略不计,因此建议只使用有状态的组件。

Vue3.x中函数式组件只能由接收 props 和 context (即:slots、attrs、emit) 的普通函数创建。
 
(2). 单文件组件 (SFC) <template> 标签的 functional attribute 和函数式组件的 functional 选项已被移除。

(3). 异步组件现在需要通过 defineAsyncComponent 方法进行创建。

新的 defineAsyncComponent 助手方法,用于显式地定义异步组件。

component 选项被重命名为 loader。

Loader 函数本身不再接收 resolve 和 reject 参数,且必须返回一个 Promise。

Vue2异步组件是通过将组件定义为返回 Promise 的函数来创建的,例如:
    const asyncModal = () => import('./Modal.vue')

在 Vue 3 中,由于函数式组件被定义为纯函数,因此异步组件需要通过将其包裹在新的 defineAsyncComponent 助手方法中来显式地定义。
示例:
    import { defineAsyncComponent } from 'vue'
    import ErrorComponent from './components/ErrorComponent.vue'
    import LoadingComponent from './components/LoadingComponent.vue'

    // 不带选项的异步组件
    const asyncModal = defineAsyncComponent(() => import('./Modal.vue'))

    // 带选项的异步组件
    const asyncModalWithOptions = defineAsyncComponent({
        loader: () => import('./Modal.vue'),
        delay: 200,
        timeout: 3000,
        errorComponent: ErrorComponent,
        loadingComponent: LoadingComponent
    })

(4). 组件事件现在应该使用 emits 选项进行声明。

Vue 3 现在提供一个 emits 选项,和现有的 props 选项类似。这个选项可以用来定义一个组件可以向其父组件触发的事件。

Vue3中 emits选项会影响一个 监听器 被解析为 组件事件监听器 还是 原生DOM事件监听器,注意原生DOM事件存在冒泡触发机制【可通过在emits选项中添加对应的事件名避免被解析为原生DOM事件监听器】。


4. 渲染函数。
(1). 渲染函数 API 更改【此更改不会影响 <template> 用户】。

h 现在是需要从全局导入,而不是默认可作为参数传递给渲染函数。

更改了渲染函数参数,使其在有状态组件和函数组件的表现更加一致。

VNode 现在有一个扁平的 prop 结构。
示例:
    // 3.x 语法
    {
        class: ['button', { 'is-outlined': isOutlined }],
        style: [{ color: '#34495E' }, { backgroundColor: buttonColor }],
        id: 'submit',
        innerHTML: '',
        onClick: submitForm,
        key: 'submit-button'
    }
 
(2). $scopedSlots property 已移除,所有插槽都通过 $slots 作为函数暴露。
示例一:
    // 3.x Syntax
    h(LayoutComponent, {}, {
        header: () => h('div', this.header),
        content: () => h('div', this.content)
    })
    
示例二:
    //需要以编程方式引用作用域插槽时。
    
    // 2.x 语法
    this.$scopedSlots.header

    // 3.x 语法
    this.$slots.header()

(3). $listeners 被移除或整合到 $attrs。

$listeners 对象在 Vue 3 中已被移除。事件监听器现在是 $attrs 的一部分。

在 Vue 3 的虚拟 DOM 中,事件监听器现在只是以 on 为前缀的 attribute,这样它就成为了 $attrs 对象的一部分,因此 $listeners 被移除了。

示例:
    {
        text: '这是一个 attribute',
        onClose: () => console.log('close 事件被触发')
    }

(4). $attrs 现在包含 class 和 style attribute。


5. 自定义元素。
(1). 自定义元素检测现在在模板编译时执行。

检测并确定哪些标签应该被视为自定义元素的过程,现在会在模板编译期间执行,且应该通过编译器选项而不是运行时配置来配置。

(2). 特殊的 is attribute 的使用被严格限制在保留的 <component> 标签中。

为了支持 2.x 在原生元素上使用 is 的用例来处理原生 HTML 解析限制,Vue3 用 vue: 前缀来解析一个 Vue 组件。
示例:
    <table>
        <tr is="vue:blog-post-row"></tr>
    </table>


6. 其它小改变。
(1). beforeDestroy 生命周期选项被重命名为 beforeUnmount,destroyed 生命周期选项被重命名为 unmounted。

(2). Vue3中 选项式 生命周期选项 相比较 Vue2生命周期钩子 增加了 renderTracked【开发调试用,在一个响应式依赖被组件的渲染作用追踪后调用。】、renderTriggered【开发调试用,在一个响应式依赖被组件触发了重新渲染之后调用。】、serverPrefetch【SSR选项,在 组件实例在服务器上被渲染 之前调用】 三个选项。

(3). 生成 prop 默认值的工厂函数不再能访问 this。

Vue3组件接收到的原始 prop 将作为参数传递给默认函数,inject API 可以在默认函数中使用。
示例:
    import { inject } from 'vue'
    export default {
        props: {
            theme: {
                default (props) {
                    // `props` 是传递给组件的、
                    // 在任何类型/默认强制转换之前的原始值,
                    // 也可以使用 `inject` 来访问注入的 property
                    return inject('theme', 'default-theme')
                }
            }
        }
    }

(4). 自定义指令的 API 已更改为与组件生命周期一致,且 binding.expression 已移除。

Vue3自定义指令的钩子函数已经被重命名,以更好地与组件的生命周期保持一致。
示例:
    const MyDirective = {
        created(el, binding, vnode, prevVnode) {}, // 新增
        beforeMount() {},
        mounted() {},
        beforeUpdate() {}, // 新增
        updated() {},
        beforeUnmount() {}, // 新增
        unmounted() {}
    }

(5). data 选项应始终被声明为一个函数。

组件选项 data 的声明不再接收纯 JavaScript object,而是接收一个 function。

(6). 来自 mixin 的 data 选项现在为浅合并。

当合并来自 mixin 或 extend 的多个 data 返回值时,合并操作现在是浅层次的而非深层次的 (只合并根级属性)。

(7). Attribute 强制策略已更改。

移除 枚举attribute【包括 contenteditable、draggable 和 spellcheck】 的内部概念,并将这些 attribute 视为普通的非布尔 attribute。

如果值为布尔值 false,则不再移除 attribute。取而代之的是,它将被设置为 attr="false"。若要移除 attribute,应该使用 null 或者 undefined。

(8). Transition 的一些 class 被重命名。

过渡类名 v-enter 修改为 v-enter-from、过渡类名 v-leave 修改为 v-leave-from。

(9). <TransitionGroup> 不再默认渲染包裹元素。

<transition-group> 不再默认渲染根元素,但仍然可以用 tag attribute 创建根元素。

(10). 当侦听一个数组时,只有当数组被替换时,回调才会触发,如果需要在变更时触发,则必须指定 deep 选项。

换句话说,在数组被改变时侦听回调将不再被触发。要想在数组被改变时触发侦听回调,必须指定 deep 选项。

(11). 没有特殊指令的标记 (v-if/else-if/else、v-for 或 v-slot) 的 <template> 现在被视为普通元素,并将渲染为原生的 <template> 元素,而不是渲染其内部内容。

(12). 已挂载的应用不会替换它所挂载的元素,而是会作为子元素插入。

在 Vue 2.x 中,当挂载一个具有 template 的应用时,被渲染的内容会替换我们要挂载的目标元素。

在 Vue 3.x 中,被渲染的应用会作为子元素插入,从而替换目标元素的 innerHTML。

(13). 生命周期的 hook: 事件前缀改为 vue:。

在 Vue 2 中,我们可以通过事件来监听组件生命周期中的关键阶段。这些事件名都是以 hook: 前缀开头,并跟随相应的生命周期钩子的名字。

在 Vue 3 中,这个前缀已被更改为 vue:。额外地,这些事件现在也可用于 HTML 元素,和在组件上的用法一样。
示例一:
    <template>
        <child-component @vue:updated="onUpdated">
    </template>
示例二:
    <template>
        <input @vue:mounted="({ el }) => el.focus()">
    </template>
    
(14). 对于组件间的逻辑复用,推荐使用组合式 API 的组合式函数,而不是mixins。

(15). Vue3中,number 修饰符会在输入框有 type="number" 时自动启用。而Vue2中不会。


7. 被移除的 API。
(1). Vue3不再支持使用数字 (即键码) 作为 v-on 修饰符,不再支持 config.keyCodes。

从 KeyboardEvent.keyCode 已被废弃开始,Vue 3 继续支持这一点就不再有意义了。因此,现在建议对任何要用作修饰符的键使用 kebab-cased (短横线) 名称。
示例:
    <!-- Vue 3 在 v-on 上使用按键修饰符 -->
    <input v-on:keyup.page-down="nextPage">

    <!-- 同时匹配 q 和 Q -->
    <input v-on:keypress.q="quit">

(2). $on,$off 和 $once 实例方法已被移除,组件实例不再实现事件触发接口。

(3). 从 Vue 3.0 开始,过滤器 (filter)已移除,且不再支持。

(4). 对 内联模板 attribute【inline-template】的支持已被移除。

(5). Vue 3.0 中 $children 实例 property 已移除,不再支持。

(6). propsData 选项之前用于在创建 Vue 实例的过程中传入 prop,现在它被移除了。如果想为 Vue 3 应用的根组件传入 prop,请使用 createApp 的第二个参数。

(7). 已移除 $destroy 实例方法。用户不应该再手动管理单个 Vue 组件的生命周期。

(8). 已移除 全局函数 set 和 delete 以及实例方法 $set 和 $delete。基于代理的变化检测已经不再需要它们了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/705454.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【uni-app】常用组件和 API

常用组件 uni-app 为开发者提供了一系列基础组件&#xff0c;类似 HTML 里的基础标签元素&#xff0c;但 uni-app 的组件与 HTML 不同&#xff0c;而是与小程序相同&#xff0c;更适合手机端使用。 虽然不推荐使用 HTML 标签&#xff0c;但实际上如果开发者写了div等标签&…

基于uniapp大学生社团活动管理系统python+java+node.js+php微信小程序

uni-app框架&#xff1a;使用Vue.js开发跨平台应用的前端框架&#xff0c;编写一套代码&#xff0c;可编译到Android、小程序等平台。 语言&#xff1a;pythonjavanode.jsphp均支持 框架支持:springboot/Ssm/thinkphp/django/flask/express均支持 运行软件:idea/eclipse/vscod…

关于 REST API 和 SOAP,你知道多少?

背景 通过上篇文章 关于 REST API&#xff0c;你了解多少&#xff1f;&#xff0c;我们知道REST API是在Web应用程序的发展过程中产生的。在Web应用程序的早期阶段&#xff0c;应用程序之间的通信主要是通过SOAP&#xff08;Simple Object Access Protocol&#xff09;和XML-R…

递归和迭代【Py/Java/C++三种语言详解】LeetCode每日一题240218【树DFS】LeetCode 589、 N 叉树的前序遍历

有LeetCode算法/华为OD考试扣扣交流群可加 948025485 可上全网独家的 欧弟OJ系统 练习华子OD、大厂真题 绿色聊天软件戳 od1336了解算法冲刺训练 文章目录 题目描述解题思路代码方法一&#xff1a;递归法PythonJavaC时空复杂度 方法二&#xff1a;迭代法PythonJavaC时空复杂度 …

面试redis篇-08数据淘汰策略

原理 当Redis中的内存不够用时,此时在向Redis中添加新的key,那么Redis就会按照某一种规则将内存中的数据删除掉,这种数据的删除规则被称之为内存的淘汰策略。 Redis支持8种不同策略来选择要删除的key: noeviction: 不淘汰任何key,但是内存满时不允许写入新数据,默认就是…

【Pytorch】模块化

文章目录 1. 获取数据2. 创建Dataset和DataLoader3. 定义模型4. 创建训练模型引擎函数5. 创建保存模型的函数6. 训练、评估并保存模型 模块化涉及将jupyter notebook代码转换为一系列提供类似功能的不同 Python 脚本。 可以将笔记本代码从一系列单元格转换为以下 Python 文件&…

JetBrains系列工具,配置PlantUML绘图

PlantUML是一个很强大的绘图工具&#xff0c;各种图都可以绘制&#xff0c;具体的可以去官网看看&#xff0c;或者百度。 PlantUML简述 https://plantuml.com/zh/ PlantUML语言参考指引 https://plantuml.com/zh/guide PlantUML语言是依赖Graphviz进行解析的。Graphviz是开源…

[设计模式Java实现附plantuml源码~行为型] 撤销功能的实现——备忘录模式

前言&#xff1a; 为什么之前写过Golang 版的设计模式&#xff0c;还在重新写Java 版&#xff1f; 答&#xff1a;因为对于我而言&#xff0c;当然也希望对正在学习的大伙有帮助。Java作为一门纯面向对象的语言&#xff0c;更适合用于学习设计模式。 为什么类图要附上uml 因为很…

2024程序员容器化上云之旅-第6集-Ubuntu-WSL2-Windows11版:艰难复活

故事梗概 Java程序员马意浓在互联网公司维护老旧电商后台系统。 渴望学习新技术的他在工作中无缘Docker和K8s。 他开始自学Vue3并使用SpringBoot3完成了一个前后端分离的Web应用系统&#xff0c;并打算将其用Docker容器化后用K8s上云。 8 复活重生 周末终于有点属于自己的…

【书籍分享 • 第三期】虚拟化与容器技术

文章目录 一、本书内容二、读者对象三、编辑推荐四、前言4.1 云计算技术的发展4.2 KVM、Docker4.3 本书内容简介4.4 作者简介 五、粉丝福利 一、本书内容 《虚拟化与容器技术》通过深入浅出的方式介绍KVM虚拟化技术与Docker容器技术的概念、原理及实现方法&#xff0c;内容包括…

Linux之安装Nginx、前后端分离项目部署

目录 一、安装Nginx 1.1先一键安装4个依赖 1.2下载并解压安装包 1.3安装nginx&#xff0c;一般我们在nginx都是要安装ssl证书的 1.4 启动nginx服务 1.5开放80端口 1.6配置nginx自启动 1.7修改/etc/rc.d/rc/local的权限 二、多个tomcat负载加后端部署 2.1创建多个tomca…

Windows已经安装了QT 6.3.0,如何再安装一个QT 5.12

要在Windows上安装Qt 5.12&#xff0c;您可以按照以下步骤操作&#xff1a; 下载Qt 5.12&#xff1a;访问Qt官方网站或其他可信赖的来源&#xff0c;下载Qt 5.12的安装包。 下载安装地址 下载安装详细教程 安装问题点 qt安装时“Error during installation process(qt.tools…

react useRef用法

1&#xff0c;保存变量永远不丢失 import React, { useState,useRef } from react export default function App() { const [count,setcount] useState(0) var mycount useRef(0)//保存变量永远不丢失--useRef用的是闭包原理 return( <div> <button onClick{()>…

跨境电商营销进化史:从传统广告到智能化策略的全面探析

随着全球化的不断推进和互联网技术的飞速发展&#xff0c;跨境电商在过去几年里取得了显著的发展。在这个竞争激烈的市场中&#xff0c;企业们纷纷调整营销策略以应对不断变化的消费者需求和市场趋势。本文Nox聚星将和大家探讨跨境电商营销策略的演变过程&#xff0c;从传统的推…

MySQL基础(二)

文章目录 MySQL基础&#xff08;二&#xff09;1. 数据库操作-DQL1.1 介绍1.2 语法1.3 基本查询1.4 条件查询1.5 聚合函数1.6 分组查询1.7 排序查询1.8 分页查询1.9 案例1.9.1 案例一1.9.2 案例二 2. 多表设计2.1 一对多2.1.1 表设计2.1.2 外键约束 2.2 一对一2.3 多对多2.4 案…

【Spring Boot 3】【JPA】@ManyToOne 实现一对多单向关联

【Spring Boot 3】【JPA】@ManyToOne 实现一对多单向关联 背景介绍开发环境开发步骤及源码工程目录结构总结背景 软件开发是一门实践性科学,对大多数人来说,学习一种新技术不是一开始就去深究其原理,而是先从做出一个可工作的DEMO入手。但在我个人学习和工作经历中,每次学…

Python爬虫中的单线程、多线程问题(文末送书)

前言 在使用爬虫爬取数据的时候&#xff0c;当需要爬取的数据量比较大&#xff0c;且急需很快获取到数据的时候&#xff0c;可以考虑将单线程的爬虫写成多线程的爬虫。下面来学习一些它的基础知识和代码编写方法。 一、进程和线程 进程可以理解为是正在运行的程序的实例。进…

【Flink精讲】Flink反压调优

Flink 网络流控及反压的介绍&#xff1a; Apache Flink学习网 反压的理解 简单来说&#xff0c; Flink 拓扑中每个节点&#xff08;Task&#xff09;间的数据都以阻塞队列的方式传输&#xff0c;下游来不及消费导致队列被占满后&#xff0c;上游的生产也会被阻塞&#xff0c;…

dpvs 笔记

20、 基于ECMP的多活负载均衡策略 当使用ospf/ECMP来实现高可用&#xff0c;所以keepalived不需要配置vrrp功能。keepalived只使用后端服务健康检查功能。 Equal-Cost Multi-Path Routing (ECMP) ECMP根据SIP-DIP对来选择路由 keepalived 健康检查机制说明 keepalived TCP chec…

深入探索计算机组成原理:构建信息时代的基石

### 深入探索计算机组成原理&#xff1a;构建信息时代的基石 在当代社会&#xff0c;计算机已经渗透到我们生活的方方面面&#xff0c;从家庭到工作场所&#xff0c;从基础科学研究到工业生产&#xff0c;无一不受到其深远影响。这一切的基础都建立在对计算机组成原理的深入理…