Vue2 ➔ Vue3 都做了哪些改变?

Vue 2 vs. Vue 3: What Are the Differences and Which Version Should You  Choose?

不是吧,兄弟,Vue3 都出来多久了,你还对这个感兴趣,说!是不是没好好卷?😏

俺也一样 😂,Vue3 出来之后只是简单了解了一下,然后还是转头一直在写 Vue2。当然,这也和大家搬砖 🧱 的处境有关。一般情况下,用 Vue2 起的项目没有什么大的问题,谁又会耗费经历去迁移呢?

不过自己在有机会单独写 H5 的时候,还是会有意识的去试试 Vue3 的。感觉 Vue2 如果掌握的不错的话,其实学习 Vue3 也没什么大的成本,但如果突然让你总结一下 Vue2 和 Vue3 的区别,你能答上来多少呢?数据响应式?生命周期?阿巴阿巴... 😅

其实官方 Vue3 迁移指南 早就给出了详细的说明,这里对一些常用的做下些总结,一起看看吧,Let's go!🚀

1. 语法上

1.1 指令模板相关

  • 移除 v-on.native 修饰符

在 Vue 2 中,v-on.native 修饰符使得组件的事件侦听器可以直接绑定到组件根元素上的原生事件。至于为什么要在 Vue3 中移除,网上有这样的解释:Vue2 这种方式并不符合组件的封装和规范性,因为组件应该将自己的行为和内部实现细节封装起来,而不是直接依赖于父级组件的事件。

Vue 3 更加倡导组件的封装性和独立性,因此移除了v-on.native 修饰符,鼓励使用更明确的方式进行事件传递和处理。有道理 🤔

  • v-model 语法调整,v-model:title="title",代替了之前的 v-model 和 .sync
<!-- Vue2: -->
<ChildComponent v-model="pageTitle" />
<!-- 是以下的简写: -->
<ChildComponent :value="pageTitle" @input="pageTitle = $event" /><ChildComponent :title.sync="pageTitle" />
<!-- 是以下的简写: -->
<ChildComponent :title="pageTitle" @update:title="pageTitle = $event" /><!-- Vue3: -->
<ChildComponent v-model:title="pageTitle" />
<!-- 是以下的简写: -->
<ChildComponent :title="pageTitle" @update:title="pageTitle = $event" />

1.2 组件相关

  • 异步组件的调整,路由懒加载的组件需要用 defineAsyncComponent 关键字包裹 📦
  • emit 选项可以定义组件可向父组件触发的事件,同 props
// 数组语法
export default {emits: ['check'],created() {this.$emit('check')}
}// 对象语法
export default {emits: {// 没有验证函数click: null,// 具有验证函数submit: (payload) => {if (payload.email && payload.password) {return true} else {console.warn(`Invalid submit event payload!`)return false}}}
}

1.3 渲染函数

  • $listeners 合并至 $attrs
  • $attrs 现在包含了所有传递给组件的 attribute,包括 class 和 style

1.4 移除的 API

  • createApp() 代替 new Vue()
  • ​从实例中完全移除了 $on、$off 和 $once 方法,通过 new Vue() 方式实现的事件总线不再可用 😅。官方推荐用外部的、实现了事件触发器接口的库, 如 mitt 或 tiny-emitter

1.5 其他

  • 根元素可以有不止一个标签了
  • create 生命周期被 setup 代替,destroyed 被改名为 unmounted
  • data 选项已标准化为只接受返回 object 的 function
  • watch 可以侦听数组时候,必须指定 deep 才能侦听到数组元素的改变
  • 新增了 <Teleport> 传送门
  • ref 支持函数了

2. 数据响应式

2.1 Vue2 数据响应式原理

老生常谈的问题,再赘述一遍 😐

Vue2 对数据的劫持是用的 Object.defineProperty,但这种方式其实是有缺点的 👀

  • 对于未初始化但却直接在 DOM 上引用的变量,并不能做到响应式 ➡️ 补救:$set
  • 对于数组类型的数据,通过下标改变的方式达不到响应式 ➡️ 补救:使用改写的数组 API
Object.defineProperty(obj, key, val) {enumerable: true,configurable: true,get: function reactiveGetter() {return val},set: function reactiveSetter(newVal) {if(newVal === val) returnval = newValdep.notify() // 通知依赖该属性的其他组件进行更新}
}

2.2 Vue3 数据响应式原理

​Vue3 弥补了 Object.defineProperty 的两个不足:

  • Vue2 中动态创建的 data 属性需要通过 Vue.$set 来赋,Proxy 则不需要
  • 基于性能的考虑,Vue2 篡改了数组的 7 个 API,Proxy 则不需要

defineProperty 需要提前递归遍历 data 做到响应式,而 Proxy可以在真正用到深层数据时候再做响应式(惰性)🐂🍺

funciton reactive(obj) {return new Proxy(obj, {get(target, key, receiver) {const res = Reflect.get(target, key, receiver)track(target, key) // 收集依赖return isObject(res) ? reactive(res) : res},set(target, key, value, receiver) {const oldValue = target[key]const result = Reflect.set(target, key, value, receiver)if(result && oldValue !== value) {trigger(target, key) // 触发更新}return result}})
}

3. Composition API

 Vue 官方:组合式 API 常见问答:组合式 API (Composition API) 是一系列 API 的集合,使我们可以使用函数而不是声明选项的方式书写 Vue 组件。它是一个概括性的术语,涵盖了以下方面的 API:

在 Vue 3 中,组合式 API 基本上都会配合 <script setup> 语法在单文件组件中使用。下面是一个使用组合式 API 的组件示例:

<template><button @click="increment">点击了:{{ count }} 次</button>
</template><script setup>
import { ref, onMounted } from 'vue'// 响应式状态
const count = ref(0)// 更改状态、触发更新的函数
function increment() {count.value++
}// 生命周期钩子
onMounted(() => {console.log(`计数器初始值为 ${count.value}。`)
})
</script>

为什么要用 Composition API?

Vue 官方:组合式 API 常见问答 里也说了为什么,比如更好的逻辑复用、类型推导、更灵活的代码组织、更小的生产包体积。🐂🍺

此外,我还了解大概是 2019 年 6月,尤雨溪发表了一篇 Composition API 的文章:「Vue Function-based API RFC」 ,详细阐述了为什么要出新的 API,其描述的设计思路大致总结如下:

  • 响应式 API:例如 ref() 和 reactive(),使我们可以直接创建响应式状态、计算属性和侦听器。
  • 生命周期钩子🪝:例如 onMounted() 和 onUnmounted(),使我们可以在组件各个生命周期阶段添加逻辑。
  • 依赖注入:例如 provide() 和 inject(),使我们可以在使用响应式 API 时,利用 Vue 的依赖注入系统。
  • Composition API 比 mixins、高阶组件、Renderless Components 更好:
    • 模版中的数据来源不清晰。举例来说,当一个组件中使用了多个 mixin 的时候,光看模版会很难分清一个属性到底是来自哪一个 mixin。HOC 也有类似的问题。
    • 命名空间冲突。由不同开发者开发的 mixin 无法保证不会正好用到一样的属性或是方法名。HOC 在注入的 props 中也存在类似问题。
    • 性能。HOC 和 Renderless Components 都需要额外的组件实例嵌套来封装逻辑,导致无谓的性能开销。
  • Composition API 更适合 TypeScript,Vue2 的装饰器结合 TypeScript 非常难用。

ps:不知道大家有没有关注过 Vue3 的整个推出过程,我记得 Vue3 一开始公布的想法是推出一个基于 Class 的 API,忘记是在哪里偶然看到的了。那个时候 React 推出了 hooks 的概念,不知道是不是觉的 hooks 的概念更好,但是又不能直接叫 hooks API,所以就叫 Composition API。

此外,当时还有一个潮流,大家好像都在从 JS 往 TS 上靠,Vue 应该也想和 TypeScript 结合的更紧密,单 Vue2 装饰器的写法非常麻烦,于是乎一石二鸟,Composition API 即赶上了最新的 API 风格,又赶上了最新的语言风格。ps:也许是我凭空 yy 🤔

​从个人的角度来讲,作为 Vue 的使用者,我感觉 Vue3 比 React 要好。因为 Vue3 是在 React 后推出的,它看到 hooks API 之后才发明的 Composition API,那它就避免了 React 中的几个显著的问题,比如:不能获取最新的值,手动写依赖不太容易写好,可能某个依赖忘写导致不更新...

end 🎉

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

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

相关文章

基于weka手工实现多层感知机(BPNet)

一、BP网络 1.1 单层感知机 单层感知机&#xff0c;就是只有一层神经元&#xff0c;它的模型结构如下1&#xff1a; 对于权重 w w w的更新&#xff0c;我们采用如下公式&#xff1a; w i w i Δ w i Δ w i η ( y − y ^ ) x i (1) w_iw_i\Delta w_i \\ \Delta w_i\eta(y…

Maven —— 项目管理工具

前言 在这篇文章中&#xff0c;荔枝会介绍如何在项目工程中借助Maven的力量来开发&#xff0c;主要涉及Maven的下载安装、环境变量的配置、IDEA中的Maven的路径配置和信息修改以及通过Maven来快速构建项目。希望能对需要配置的小伙伴们有帮助哈哈哈哈~~~ 文章目录 前言 一、初…

设计模式-组合模式在Java中的使用示例-杀毒软件针对文件和文件夹进行杀毒

场景 组合模式 组合模式(Composite Pattern)&#xff1a; 组合多个对象形成树形结构以表示具有“整体—部分”关系的层次结构。 组合模式对单个对象&#xff08;即叶子对象&#xff09;和组合对象&#xff08;即容器对象&#xff09;的使用具有一致性&#xff0c; 组合模式…

排序算法之冒泡排序详解-python版

冒泡排序&#xff1a;通过比较2个相邻元素之间的大小&#xff0c;交换元素顺序&#xff0c;从而达到排序目的。 从百度百科摘抄下来的冒泡排序原理如下&#xff1a; 比较相邻的元素。如果第一个比第二个大&#xff0c;就交换他们两个。 对每一对相邻元素做同样的工作&#xf…

elementUI 非表单格式的校验

在普通表单中对输入框、选择框都有校验案例。 但是在自定义非空中如何进行校验官网并没有说明 关键代码 clearValidate 方法清除校验 this.$refs.formValue.clearValidate(signinimg) 使用案例 <template><div class"stylebg"><Tabs icons"el-…

MySQL原理探索——31 误删数据后除了跑路,还能怎么办

在前面几篇文章中&#xff0c;介绍了 MySQL 的高可用架构。当然&#xff0c;传统的高可用架构是不能预防误删数据的&#xff0c;因为主库的一个 drop table 命令&#xff0c;会通过 binlog 传给所有从库和级联从库&#xff0c;进而导致整个集群的实例都会执行这个命令。 虽然我…

blender 阵列修改器

效果 tab 键进入编辑模式&#xff0c;全选制作好的模型&#xff0c;gx 移动模型置于游标原点&#xff1b; 阵列修改器&#xff1a; 相对偏移&#xff1a;以物体的长宽高为比例&#xff0c;调整x y z 的数值&#xff0c;在 x y z 方向上做不同比例的偏移&#xff1b; 恒定偏移…

C#安装.Net平台科学计算库Math.Net Numerics

工作的时候需要使用到C#的Math.Net库来进行计算。 Math.Net库涵盖的主题包括特殊函数&#xff0c;线性代数&#xff0c;概率模型&#xff0c;随机数&#xff0c;插值&#xff0c;积分&#xff0c;回归&#xff0c;优化问题等。 这里记录一下&#xff0c;安装Math.Net库的过程…

Linux 部署Vue+Spring Boot项目

部署Vue Spring Boot项目 安装redis wget http://download.redis.io/releases/redis-4.0.8.tar.gz tar -zxvf redis-4.0.8.tar.gz yum install gcc-c make make install如果出现下面的问题&#xff1a; yum install tcl make testredis-server myconifg/redis.conf输入客户端…

[JVM] 2. 类加载子系统(1)-- 内存结构、类加载子系统概述

一、内存结构 类加载子系统的职责是&#xff1a;加载class文件到内存中。 完整的内存结构如下&#xff1a; 二、类加载过程 类加载过程总体分为Loading&#xff08;加载&#xff09;、Linking&#xff08;链接&#xff09;、Initialization&#xff08;初始化&#xff09;三…

HarmonyOS学习路之方舟开发框架—学习ArkTS语言(基本语法 五)

Styles装饰器&#xff1a;定义组件重用样式 如果每个组件的样式都需要单独设置&#xff0c;在开发过程中会出现大量代码在进行重复样式设置&#xff0c;虽然可以复制粘贴&#xff0c;但为了代码简洁性和后续方便维护&#xff0c;我们推出了可以提炼公共样式进行复用的装饰器St…

一文读懂 MySQL 中的索引

文章目录 1. 索引概述1.1 索引概述1.2 优点1.3 缺点1.6 常见索引概念1.6.1 聚簇索引1.6.2 二级索引&#xff08;辅助索引、非聚簇索引&#xff09;1.6.3 联合索引 1.8 MyISAM索引的原理1.9 MyISAM 与 InnoDB对比1.10 索引的代价 2. 索引的创建与设计原则2.1 索引的声明与使用2.…