当前位置: 首页 > news >正文

前端系列-7 Vue3响应式数据

1.响应式数据和实现

响应式数据的核心是当数据模型发生变化时,与之相关(使用该数据模型)的视图或组件可以自动更新,以反映最新的数据状态。
实现原理是数据劫持、依赖收集和分发更新,数据劫持是一种AOP策略。
在vue2中通过Object.defineProperty方法为对象的每个属性设置setter和getter方法,当访问或者修改对象的属性时,进入setter/getter方法,从而实现拦截。getter方法被调用时,可以进行依赖收集,确认属性被哪些组件依赖;setter方法被调用时,则进行分发更新,将属性的更新事件发送到对应依赖的组件。
在vue3中,通过Proxy创建一个对象的代理,从而可以拦截其属性的读取、设置等操作。Proxy相对于Object.defineProperty具有更大和更灵活的数据拦截能力,并且优化了内存使用。

2.使用方式

2.1 ref

当基本类型变量或者对象通过ref函数包裹后,形成响应式数据对象,使用方式如下:

<template><div><p>姓名:{{name}}</p><button @click="changeName">修改名字</button></div>
</template><script setup lang="ts">import { ref } from 'vue';let name =ref('ewen');function changeName() {name.value = "ewens";console.log(name);console.log(name.value);    }
</script>

浏览器Console显示name为RefImpl类型对象,value属性存放实际的数值:

RefImpl {__v_isShallow: false, dep: Map(1), __v_isRef: true, _rawValue: "ewens", _value: "ewens"}
App.vue:8 ewens

说明:在template组件中直接使用name, 而在script中使用name.value进行取值和设值。

2.2 reactive

reactive只能用于对象和数组类型,不能用于基本类型

当对象或数组通过reactive函数包裹后,形成响应式数据对象,使用方式如下:

<template><div><p>姓名:{{person.name}}</p><p>年龄:{{person.age}}</p><button @click="changeName">修改名字</button><button @click="changeAge">修改年龄</button></div>
</template><script lang="ts" setup name="Person">
import { reactive } from 'vue'// person 是一个Proxy类型的对象
let person = reactive({ name: 'ewen', age: 18})function changeName() {person.name = 'ewens'
}
function changeAge(){person.age = 999
}
</script>

说明:在template组件和script块中直接使用对象.属性名进行取值和设值。

2.3 toRef与toRefs

当希望从响应式对象中提取某个属性,且希望保持这个属性的响应性,可以通过toRef和toRefs来实现。

import {reactive,toRefs,toRef} from 'vue'let person = reactive({ name: 'ewen', age: 18})
// 使用toRef可以提取响应式对象的某个属性
const name = toRef(person, 'name');
const age = toRef(person, 'age');//使用toRef可以一次性提取响应式对象的多个属性:
const { name, age } = toRefs(person);

在响应式属性提取之后,在template组件或者script脚本中原本需要使用person.name的地方也可以使用name替换,使用person.age的地方也可以使用age替换。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【简历】吉林某一本大学:JAVA秋招简历指导,简历通过率比较低
  • maven archetype
  • LeetCode 热题 HOT 100 (011/100)【宇宙最简单版】
  • 代码随想录算法训练营DAY64|拓扑排序、dijkstra(朴素版)
  • 基因组挖掘指导天然药物分子的发现-文献精读34
  • MongoDB教程(十五):MongoDB原子操作
  • 【系列专题】新质生产力之光,照亮“制造强国”之路
  • 【SpringBoot】URL映射之consumes和produces匹配、params和header匹配
  • go-kratos 学习笔记(1) 安装
  • 【数据结构】树和二叉树
  • InternLM学习笔记
  • 图解RocketMQ之消息模型详解(1)
  • Java程序中常见问题
  • Linux源码阅读笔记14-IO体系结构与访问设备
  • LC61----1374. 生成每种字符都是奇数个的字符串(字符串)---java版
  • HTTP请求重发
  • Java多线程(4):使用线程池执行定时任务
  • JS+CSS实现数字滚动
  • PHP面试之三:MySQL数据库
  • Redux 中间件分析
  • Terraform入门 - 3. 变更基础设施
  • 闭包--闭包之tab栏切换(四)
  • 干货 | 以太坊Mist负责人教你建立无服务器应用
  • 缓存与缓冲
  • 简单易用的leetcode开发测试工具(npm)
  • 精益 React 学习指南 (Lean React)- 1.5 React 与 DOM
  • 如何选择开源的机器学习框架?
  • 小李飞刀:SQL题目刷起来!
  • - 语言经验 - 《c++的高性能内存管理库tcmalloc和jemalloc》
  • 正则表达式小结
  • 自动记录MySQL慢查询快照脚本
  • FaaS 的简单实践
  • ‌JavaScript 数据类型转换
  • (01)ORB-SLAM2源码无死角解析-(56) 闭环线程→计算Sim3:理论推导(1)求解s,t
  • (C#)Windows Shell 外壳编程系列9 - QueryInfo 扩展提示
  • (C语言版)链表(三)——实现双向链表创建、删除、插入、释放内存等简单操作...
  • (Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九
  • (ZT)北大教授朱青生给学生的一封信:大学,更是一个科学的保证
  • (ZT)薛涌:谈贫说富
  • (每日持续更新)jdk api之StringBufferInputStream基础、应用、实战
  • (三)终结任务
  • (一)utf8mb4_general_ci 和 utf8mb4_unicode_ci 适用排序和比较规则场景
  • (转)关于pipe()的详细解析
  • (转)详解PHP处理密码的几种方式
  • (自用)交互协议设计——protobuf序列化
  • *(长期更新)软考网络工程师学习笔记——Section 22 无线局域网
  • .NET Framework与.NET Framework SDK有什么不同?
  • .NET6 开发一个检查某些状态持续多长时间的类
  • .net中应用SQL缓存(实例使用)
  • .pyc文件还原.py文件_Python什么情况下会生成pyc文件?
  • @Bean注解详解
  • @Controller和@RestController的区别?
  • @private @protected @public
  • @RequestMapping 和 @GetMapping等子注解的区别及其用法
  • @vue/cli脚手架