前端宝典二十六:vue3的新特性

一、Vue2处理响应式的源码方式:

const initData =  {value: 1
}
const data = {};Object.keys(initData).forEach(key => {Object.defineProperty(data, key, {get() {return initData[key]},set(value) {initData[key] = value}})
})console.log(data.value) // 1
initData.value2 = 4;
console.log(initData.value2) // 4
console.log(data.value2) // undefined

修改initData.value2的值,data值没有修改,这是因为初始化劫持时已经拿到了initData所有的key,然后使用Object.defineProperty来修改getter和setter方法,如果再用initData.value2 = 4方法修改,data是拿不到更新的值的
因此,在Vue2中有几种修改方式是无法更新data值的:

  • 当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue
  • 当你修改数组的长度时,例如:vm.items.length = newLength

为了解决第一类问题,以下两种方式都可以实现和 vm.items[indexOfItem] = newValue 相同的效果,同时也将触发状态更新:

// Vue.set
Vue.set(example1.items, indexOfItem, newValue)
// Array.prototype.splice
example1.items.splice(indexOfItem, 1, newValue)

为了解决第二类问题,你可以使用 splice:

example1.items.splice(newLength)

为了解决Vue2中的问题,Vue3进行了修改

二、Vue3处理响应式的方式

const initData =  {value: 1
}const proxy = new Proxy(initData, {get(target, key, receiver) {return Reflect.get(target, key, receiver)},set(target, key, value, receiver) {return Reflect.set(target, key, value, receiver);}
}) console.log(proxy.value)
proxy.value = 2
console.log(proxy.value)

Reflect与Proxy的handler结合,修改getter和setter方法,实现数据劫持响应

三、Vue3响应式的使用方式

在 Vue 3 中,refreactiveshallowReactiveshallowReftoRefstoRef都用于处理响应式数据,但它们之间存在一些区别。

一、ref

ref用于创建一个响应式的数据对象,内部包含一个值,访问时需要通过 .value属性。

示例代码:

<template><div><p>{{ counter }}</p><button @click="increment">Increment</button></div>
</template><script>
import { ref } from 'vue';export default {setup() {const counter = ref(0);const increment = () => {counter.value++;};return {counter,increment};}
};
</script>

在这个例子中,counter是一个使用ref创建的响应式变量,通过修改counter.value来更新其值,视图也会随之更新。

注意:
ref只追踪对 .value 的直接修改。如果 .value 是一个对象,内部属性的修改不会自动触发响应。但可以通过 reactive 包裹 .value 内部的对象来实现深度响应性。
例如:const objRef = ref({ prop: 1 }); objRef.value.prop = 2;(这不会触发响应,除非使用特殊方法如 Vue.set(objRef.value, 'prop', 2))。
二、reactive

reactive用于创建一个响应式的对象。它会深度响应式地追踪对象内所有属性的变化。

示例代码:

<template><div><p>{{ person.name }}</p><p>{{ person.age }}</p><button @click="updatePerson">Update Person</button></div>
</template><script>
import { reactive } from 'vue';export default {setup() {const person = reactive({name: 'John',age: 30});const updatePerson = () => {person.name = 'Jane';person.age++;};return {person,updatePerson};}
};
</script>

这里,person对象是使用reactive创建的响应式对象,修改其属性会触发视图更新。
reactive深度响应式地追踪对象内所有属性的变化。当对象的属性被修改时,会自动触发响应。
例如:const obj = reactive({ prop: 1 }); obj.prop = 2;(这会触发响应)。

因此:

  • 如果只是对值的响应式请用ref
  • 如果是对复杂对象的响应式请用reactive

三、shallowReactive

shallowReactive创建一个响应式对象,但只对对象的第一层属性进行追踪,不会深度追踪嵌套对象的属性变化。

示例代码:

<template><div><p>{{ shallowPerson.name }}</p><p>{{ shallowPerson.age }}</p><p>{{ shallowPerson.nestedObj.prop }}</p><button @click="updateShallowPerson">Update Shallow Person</button></div>
</template><script>
import { shallowReactive } from 'vue';export default {setup() {const shallowPerson = shallowReactive({name: 'John',age: 30,nestedObj: {prop: 'initial'}});const updateShallowPerson = () => {shallowPerson.name = 'Jane';shallowPerson.age++;// 修改嵌套对象的属性,不会触发视图更新shallowPerson.nestedObj.prop = 'updated';};return {shallowPerson,updateShallowPerson};}
};
</script>

四、shallowRef

shallowRef创建一个响应式的引用,但只追踪对其 .value的直接修改,不会深度追踪其 .value内部属性的变化。

示例代码:

<template><div><p>{{ shallowRefValue.num }}</p><button @click="updateShallowRefValue">Update Shallow Ref Value</button></div>
</template><script>
import { shallowRef } from 'vue';export default {setup() {const shallowRefValue = shallowRef({ num: 1 });const updateShallowRefValue = () => {// 直接修改 shallowRefValue.value 会触发更新shallowRefValue.value = { num: 2 };// 修改 shallowRefValue.value 内部属性不会触发更新shallowRefValue.value.num = 3;};return {shallowRefValue,updateShallowRefValue};}
};
</script>

五、toRefs

toRefs用于将一个响应式对象转换为一组属性的引用,这样可以在解构响应式对象时保持属性的响应性。

示例代码:

<template><div><p>{{ name }}</p><p>{{ age }}</p><button @click="updatePerson">Update Person</button></div>
</template><script>
import { reactive, toRefs } from 'vue';export default {setup() {const person = reactive({name: 'John',age: 30});// 使用 toRefs 将 person 转换为一组引用const { name, age } = toRefs(person);const updatePerson = () => {person.name = 'Jane';person.age++;};return {name,age,updatePerson};}
};
</script>

六、toRef

toRef创建一个对响应式对象中某个特定属性的引用。

示例代码:

<template><div><p>{{ personName }}</p><button @click="updatePersonName">Update Person Name</button></div>
</template><script>
import { reactive, toRef } from 'vue';export default {setup() {const person = reactive({name: 'John',age: 30});const personName = toRef(person, 'name');const updatePersonName = () => {personName.value = 'Jane';};return {personName,updatePersonName};}
};
</script>

综上所述,refreactive分别用于创建单个响应式值和对象,shallowReactiveshallowRef提供了更浅层的响应性追踪,toRefs用于在解构响应式对象时保持属性的响应性,toRef用于创建对特定属性的引用。在实际应用中,可以根据具体需求选择合适的方法来处理响应式数据。

四、watch

watch(()=> state.count, (val, oldVal)=>{console.log('watch', val, oldVal)
})
watch([()=> state.count, ()=> state.name], ([val1, val2], [oldVal1, oldVal2])=>{

这里有两种,一种是监听单个,一种是监听数组

五、 Vue 3 相比 Vue 2 有很多新特性

以下是一些主要的方面:

一、性能提升

  1. 编译优化:

    • 静态提升(Static Hoisting):Vue 3 在编译阶段会分析模板,将静态的节点提升到渲染函数之外,避免在每次渲染时重复创建。这可以提高运行时的性能,特别是在大型应用中。
    • 补丁算法优化:Vue 3 的虚拟 DOM 补丁算法更加高效,能够快速识别和更新变化的部分,减少不必要的 DOM 操作。
    • 事件监听缓存:对于频繁触发的事件监听器,Vue 3 会进行缓存,避免在每次更新时重新绑定事件监听器,提高性能。
  2. 体积更小:Vue 3 进行了优化,整体包体积更小,使得应用加载更快,占用的网络带宽更少。

二、组合式 API(Composition API)

  1. 更好的逻辑复用:组合式 API 允许开发者将相关的逻辑封装在函数中,然后在不同的组件中复用这些函数。这使得逻辑复用更加灵活和可维护,避免了在 Vue 2 中使用 mixins 可能带来的命名冲突和不清晰的问题。
  2. 更清晰的代码结构:通过组合式 API,可以将组件的逻辑按照功能进行分组,使得代码结构更加清晰,易于理解和维护。例如,可以将数据获取、状态管理、副作用处理等分别封装在不同的函数中。
  3. 响应式系统改进:Vue 3 的响应式系统基于 Proxy 对象实现,相比 Vue 2 的 Object.defineProperty 更加高效和强大。可以直接监听对象和数组的变化,而不需要进行额外的处理。

三、Teleport(传送门)

Vue 3 引入了 Teleport 组件,允许将一个组件的模板内容传送到指定的 DOM 节点中,而不是在组件的父级层次结构中渲染。这在处理模态框、弹出窗口等场景时非常有用,可以将这些元素渲染到页面的特定位置,而不受组件层次结构的限制。

四、Fragments(片段)

在 Vue 2 中,组件的模板必须有一个根元素。而在 Vue 3 中,可以使用 Fragments,即组件的模板可以没有根元素,多个元素可以直接作为组件的模板内容。这使得模板更加灵活,特别是在处理复杂的布局时。

五、Emits 选项的改进

Vue 3 对组件的 emits 选项进行了改进,使其更加严格和明确。可以在 emits 选项中定义组件触发的事件名称和参数类型,从而提高代码的可读性和可维护性。

六、更好的 TypeScript 支持

Vue 3 对 TypeScript 的支持更加友好,提供了更好的类型推断和类型定义。组合式 API 与 TypeScript 结合使用时,可以获得更好的类型安全和代码提示。

七、Suspense(异步组件加载)

Vue 3 改进了异步组件的加载方式,引入了 Suspense 组件,可以在异步组件加载过程中显示加载状态或错误信息。这使得异步组件的使用更加方便和用户友好。

这些只是 Vue 3 的一些主要新特性,还有其他一些小的改进和优化。总的来说,Vue 3 在性能、开发体验和功能方面都有了很大的提升,为开发者提供了更强大的工具来构建高效、可维护的前端应用。

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

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

相关文章

代码随想录Day 32|leetcode题目:501.斐波那契数、70.爬楼梯、746.使用最小花费爬楼梯

提示&#xff1a;DDU&#xff0c;供自己复习使用。欢迎大家前来讨论~ 文章目录 动态规划理论基础一、理论基础1.1 什么是动态规划1.2 动态规划的解题步骤1.3 动态规划应该如何debug 二、题目题目一&#xff1a; 509. 斐波那契数解题思路&#xff1a;动态规划递归解法 题目二&a…

设计模式学习-责任链模式

概念 使多个对象都有机会处理请求&#xff0c;从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链&#xff0c;并沿着这条链传递该请求&#xff0c;直到有对象处理它为止. 代码编写 using UnityEngine; using System.Collections; public class ChainOfResp…

《从C/C++到Java入门指南》- 26.record 类+多态

record 类多态 前言 由于 record 类比较简单&#xff0c;将他和多态放在一节中。 record 类 final类是从 Java 16开始才正式发布的&#xff0c;可以理解为一个final class&#xff0c;提供了一种更简洁紧凑的定义final类的方式。 public record Clock(int hours, int minu…

【golang-入门】环境配置、VSCode开发环境配置

golang介绍基础信息 windows环境配置安装包下载安装环境变量设置检查 VSCode开发配置插件配置在 Visual Studio Code 中安装通义灵码go hello word 参考资料 golang介绍 基础信息 golang官网&#xff1a;https://go.dev/golang学习网&#xff1a;https://studygolang.com/使用…

【嵌入式学习笔记】STM32中断配置及相关知识

中断 中断配置 1、使能GPIO 2、使能系统时钟 3、配置引脚 4、配置映射关系 5、配置EXTI 6、启用并设置EXTI #include "stm32f4xx.h" // Device header #include "sys.h" #include "delay.h" #include "led.h"…

ARM基础知识---CPU---处理器

目录 一、ARM架构 1.1.RAM---随机存储器 1.2.ROM---只读存储器 1.3.flash---闪存存储器 1.4.时钟&#xff08;振晶&#xff09; 1.5.复位 二、CPU---ARM920T 2.1.R0~R12---通用寄存器 2.2.PC程序计数器 2.3.LR连接寄存器 2.4.SP栈指针寄存器 2.5.CPSR当前程序状态寄存…

测试:TestGRPCDiscovery

目录 测试:TestGRPCDiscovery 类定义 方法 async def asyncSetUp(self): async def asyncTearDown(self): async def test_discovery(self): 总结 这是一个关于算力共享中环形结构通讯机制的项目图的功能模型解释。以下是根据所给信息对项目功能的概述: 项目结构: 项…

Windows 下载安装RabbitMQ

环境描述 windows10 Erlang 26.2.x 版本 RabbitMQ 3.13.7 因为RabbitMQ是Erlang语言开发的&#xff0c;所以必须安装 Erlang RabbitMQ官网链接: https://www.rabbitmq.com/docs/which-erlang 1.下载并安装Erlang 26.2.5 1.1下载Erlang 26.2.5 https://erlang.org/dow…

深度强化学习算法(四)(附带MATLAB程序)

深度强化学习&#xff08;Deep Reinforcement Learning, DRL&#xff09;结合了深度学习和强化学习的优点&#xff0c;能够处理具有高维状态和动作空间的复杂任务。它的核心思想是利用深度神经网络来逼近强化学习中的策略函数和价值函数&#xff0c;从而提高学习能力和决策效率…

鸿誉移民:定制化移民服务,吹响全球高效率移民的嘹亮号角!

鸿誉移民&#xff1a;定制化移民服务&#xff0c;吹响全球高效率移民的嘹亮号角&#xff01; 作为国内知名海外移民服务机构&#xff0c;鸿誉移民历经多年行业沉淀&#xff0c;拥有着极其丰富的移民咨询以及移民办理经验&#xff0c;并以咨询及时精准&#xff0c;签证快捷、通…

【数据结构】Map的使用与注意事项

文章目录 概念模型Map 的使用put() 和 get()getOrDefault()remove()keySet()entrySet() 注意事项 概念 Map 和 set 是一种专门用来进行搜索的容器或者数据结构&#xff0c;其搜索的效率与其具体的实例化子类有关。 以前常见的搜索方式有&#xff1a; 直接遍历&#xff0c;时间…

URP简洁的instance的写法

材质还是要开启enable instance&#xff0c;这是上一次的写法 https://dbbh666.blog.csdn.net/article/details/136644181 最近发现更适合我个人的习惯的写法 就是代码控制这个整个过程 C#代码是这样的&#xff0c;获取一个mesh&#xff0c;获取每个mesh的transform&#xff0c…

常见的性能测试方法!

前言 性能测试划分有很多种&#xff0c;测试方法也有很多种&#xff0c;更确切的说是由于测试方法的不同决定了测试划分的情况&#xff0c;但在测试过程中性能测试的划分没有绝对的界限&#xff0c;常用的有压力测试、负载测试和并发用户测试等。 性能测试的方法主要包括以下…

stm32之硬件I2C读写MPU6050陀螺仪、加速度传感器应用案例

系列文章目录 1. stm32之I2C通信协议 2. stm32之软件I2C读写MPU6050陀螺仪、加速度传感器应用案例 3. stm32之I2C通信外设 文章目录 系列文章目录前言一、电路接线图二、应用案例代码三、应用案例分析3.1 基本思路3.2 相关库函数介绍3.3 MPU6050模块3.1.1 模块初始化3.1.2 指定…

52 mysql 启动过程中常见的相关报错信息

前言 我们这里主要是看一下 service mysql start, service mysql stop 的过程中的一些常见的错误问题 这些 也是之前经常碰到, 但是 每次都是 去搜索, 尝试 1, 2, 3, 4 去解决问题 但是 从来未曾思考过 这个问题到底是 怎么造成的 The server quit without updating PID fil…

【系统架构设计】开发管理

【系统架构设计】开发管理 前言项目的范围、时间与成本项目范围管理项目时间管理项目成本管理 配置管理和文档管理配置管理文档管理 软件需求管理人力资源管理软件的运行与评价软件过程改进 前言 影响软件研发项目全局的因素是管理水平&#xff0c;而技术只影响局部&#xff0…

vrrp协议,主备路由器的选举

当VRRP备份组中的所有备份路由器&#xff08;BACKUP&#xff09;具有相同的优先级时&#xff0c;选举新的主路由器&#xff08;MASTER&#xff09;的过程将基于以下规则&#xff1a; IP地址优先&#xff1a;如果备份路由器的优先级相同&#xff0c;那么具有最高IP地址的路由器…

深入理解XML与JSON:数据交换格式的比较与应用

1.XML与JSON的概念 XML是一种标记语言&#xff0c;它允许开发者定义自己的标签来描述数据。其结构由元素、属性和文本内容组成。格式如下&#xff1a; <bookstore><book><title>XML Developers Guide</title><author>John Doe</author>&…

我的sql我做主!Mysql 的集群架构详解之组从复制、半同步模式、MGR、Mysql路由和MHA管理集群组

目录 Mysql 集群技术一、Mysql 在服务器中的部署方法1.1 在Linux下部署mysql1.1.1 安装依赖性&#xff1a;1.1.2 下载并解压源码包1.1.3 源码编译安装mysql1.1.4 部署mysql 二、Mysql的组从复制2.1 配置mastesr2.2 配置salve2.3 当有数据时添加slave22.4 延迟复制2.5 慢查询日志…

Python爬虫02

xml 和html 区别 jsonpath模块 场景 多层嵌套的复杂字典直接提取数据 安装 pip install jsonpath使用 from jsonpath import jsonpathret jsonpath(dict, jaonpath语法规则字符串)语法规则 eg: lxml模块&xpath语法 谷歌浏览器 xpath helper 插件 作用对当前页面…