vue3 基础-API-响应式 ref, reactive
上篇咱介绍了 CompositionAPI, 其核心思想是直接在函数作用域内定义响应式状态变量,并将从多个函数中得到的状态组合起来处理复杂问题.
然后初介绍了 setup 函数的作用, 即其是在 created 实例完全初始化之前调用的, 因此不能用 this, 它的主要作用就可以是管理我们接下来要介绍的 API. 在项目中通常扮演一个"任务调度" 的角色, 对整个单页面的逻辑起一个核心调度的作用.
响应式变量
首先, 注意上面这里有个关键词叫 响应式状态变量 那我们先用一个案例来认识该现象.
<!DOCTYPE html>
<html lang="en">
<head>
<title>响应式变量</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="root"></div>
<script>
const app = Vue.createApp({
template: `<div>{{name}}</div>`,
setup (props, context) {
let name = "youge"
// 延时器的作用是 2秒后, 将 name 的值 改为 "cj"
setTimeout(() => {
name = 'cj'
}, 2000);
return { name }
}
})
const vm = app.mount('#root')
</script>
</body>
</html>
经过 2 秒后, 发现页面的数据并没有改变 !, 这就引入了一个响应式变量的概念.
Vue3 是使用 Proxy, 它可以劫持整个data对象,然后递归返回属性的值的代理即可实现响应式;但是它的兼容性不是很好;
Vue2 是使用 Object.defineProperty,它只能劫持对象的属性,所以它需要深度遍历data中的每个属性,这种方式对于数组很不友好,而且对象观测后,新增的属性就不是响应式的,不过可以用Vue.set()来添加新的属性;
总之结论就是在 vue 中, dom 的更新由数据驱动, 将数据进行 Proxy 封装, 当数据变化时, 会自动触发模板 dom 的更新啦.
ref
像 ref, reactive 他们都是将一个 vue 将数据变量封装为响应式变量的方法啦 ( ref 的底层也是 reactive) .
在使用中呢, ref 用来处理基础类型的数据 (number, string, null, boolean, undefined) 将其变为响应式.
<!DOCTYPE html>
<html lang="en">
<head>
<title>ref</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="root"></div>
<script>
const app = Vue.createApp({
// 当时 ref 时, 这里不需要写成 name.value, 直接 name
template: `<div>{{name}}</div>`,
setup (props, context) {
const { ref } = Vue
// proxy: 将 'youge' 封装成 proxy({value: 'youge'}) 的响应式
let name = ref("youge")
// 延时器的作用是 2秒后, 将 name 的值 改为 "cj"
setTimeout(() => {
// ref 底层也是 reactive, 其实是一个对象
name.value = 'cj'
}, 2000);
return { name }
}
})
const vm = app.mount('#root')
</script>
</body>
</html>
再来一波关键点的复述, 这个蛮重要的其实, 就先不探究原理, 重在使用轮子哈:
// 1. 通过结构的方式从 Vue 中引入 ref
// 2. 响应变量 = ref(基础类型变量) 即完成包装
// 3. 通过 响应变量.value = 'xxx' 即完成数据变更
// 4. setup 直接 return 响应变量, 模板便可用, 而不用 .value 的方式
const { ref } = Vue
let name = ref("youge")
name.value = 'newValue'
`<div>{{name}}</div>`,
reactive
同 ref 一样的作用 ( ref 基于 reactive) 用来将引用类型数据 ( object, array, function ... ) 等给封装为响应式变量啦.
当然普通类型也是可以的, 就 reactive 的适普性会更强哦. 还是同上的例子, 我们用 reactive 来改写一波:
<!DOCTYPE html>
<html lang="en">
<head>
<title>reactive</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="root"></div>
<script>
const app = Vue.createApp({
template: `
<div>{{nameObj}}</div>
<div>{{nameObj.name}}</div>
`,
setup (props, context) {
const { reactive } = Vue
// proxy: 将 { name: 'youge' } 封装成 proxy({name: 'youge'}) 的响应式
let nameObj = reactive({ name: 'youge' })
setTimeout(() => {
nameObj.name = 'cj'
}, 2000);
return { nameObj }
}
})
const vm = app.mount('#root')
</script>
</body>
</html>
当然数组也是一样的啦.
setup (props, context) {
const { reactive } = Vue
let arr = reactive(['a', 'b', 'c'])
setTimeout(() => {
arr[1] = 'cj'
}, 2000);
return { arr }
}
这样通过 ref 和 reactive 将数据封装为响应式变量,则就可以代替掉原来的 data ( ) 方法啦. 这个会更加通用和方便维护的哦.
readonly
即对响应式变量进行 "只读" 的限定哈.
setup (props, context) {
const { reactive, readonly } = Vue
let arr = reactive(['a', 'b', 'c'])
// 只要用了 readonly 就不能修改啦, 会警告的
const copyArr = readonly(arr)
setTimeout(() => {
arr[1] = 'cj'
copyArr[0] = 666
}, 2000);
return { arr, copyArr }
}
toRefs
它的作用其实就是将咱响应式变量中的值, 通过结构的方式获取到时也是一个响应式变量的值, 可以被模板直接引用, 就不用在模板中写类似 xxxObj.xxx 的写法啦.
一句话: 将 reactive 的数据转为 ref 数据, 也是响应式的啦.
在本例中, proxy( { name: 'youge' }) 中的值给再包装为 { name: proxy( { value: 'youge' })} 这样.
<!DOCTYPE html>
<html lang="en">
<head>
<title>toRefs</title>
<script src="https://unpkg.com/vue@3"></script>
</head>
<body>
<div id="root"></div>
<script>
const app = Vue.createApp({
template: `
<div>{{name}} : {{age}}</div>
`,
setup(props, context) {
const { reactive, toRefs } = Vue
let dataObj = reactive({ name: 'youge', age: 18 })
setTimeout(() => {
dataObj.name = 'cj'
dataObj.age = 26
}, 2000);
// toRefs: proxy({name: 'cj', age: 18}) 转为:
// name: proxy({value: 'cj'}),
// age: proxy({value: 18})
// 然后直接来一波结构赋值
const { name, age } = toRefs(dataObj)
return { name, age }
}
})
const vm = app.mount('#root')
</script>
</body>
</html>
小结
- ref 和 reactive 都是对 js 数据类型进行响应式的封装, ref 针对基础类型, reactive 针对引用类型
- ref 原理: proxy: 将 'youge' 封装成 proxy({value: 'youge'}) 的响应式
- reactive 原理: proxy: 将 { name: 'youge' } 封装成 proxy({name: 'youge'}) 的响应式
- toRefs 的作用: 将 proxy({name: 'cj' }) 转化为 { name: proxy({ value: 'cj' })}
vue3 基础-API-响应式 ref, reactive的更多相关文章
- Vue3中的响应式对象Reactive源码分析
Vue3中的响应式对象Reactive源码分析 ReactiveEffect.js 中的 trackEffects函数 及 ReactiveEffect类 在Ref随笔中已经介绍,在本文中不做赘述 本 ...
- Vue3中的响应式api
一.setup文件的认识 特点1:script 中间的内容就是一个对象 特点2:script 在第一层 定义的方法 或者 变量 => 就是这个对象 属性 => 顶层的绑定回被暴露给模板( ...
- Paip.Php Java 异步编程。推模型与拉模型。响应式(Reactive)”编程FutureData总结... 1
Paip.Php Java 异步编程.推模型与拉模型.响应式(Reactive)"编程FutureData总结... 1.1.1 异步调用的实现以及角色(:调用者 提货单) F ...
- Bootstrap<基础十> 响应式实用工具
Bootstrap 提供了一些辅助类,以便更快地实现对移动设备友好的开发.这些可以通过媒体查询结合大型.小型和中型设备,实现内容对设备的显示和隐藏. 需要谨慎使用这些工具,避免在同一个站点创建完全不同 ...
- Java9第四篇-Reactive Stream API响应式编程
我计划在后续的一段时间内,写一系列关于java 9的文章,虽然java 9 不像Java 8或者Java 11那样的核心java版本,但是还是有很多的特性值得关注.期待您能关注我,我将把java 9 ...
- vue3剖析:响应式原理——effect
响应式原理 源码目录:https://github.com/vuejs/vue-next/tree/master/packages/reactivity 模块 ref: reactive: compu ...
- Unity基于响应式编程(Reactive programming)入门
系列目录 [Unity3D基础]让物体动起来①--基于UGUI的鼠标点击移动 [Unity3D基础]让物体动起来②--UGUI鼠标点击逐帧移动 时光煮雨 Unity3D让物体动起来③—UGUI DoT ...
- WebFlux基础之响应式编程
上篇文章,我们简单的了解了WebFlux的一些基础与背景,并通过示例来写了一个demo.我们知道WebFlux是响应式的web框架,其特点之一就是可以通过函数式编程方式配置route.另外究竟什么是响 ...
- iOS开发之OC篇-响应式编程Reactive Cocoa
一.Reactive Cocoa 介绍 Reactive Cocoa 是 iOS 开发的一个 "重量级" 框架 高大上的概念:响应式编程 核心概念:信号 Signal 官方网站:h ...
- Vue.js 源码分析(四) 基础篇 响应式原理 data属性
官网对data属性的介绍如下: 意思就是:data保存着Vue实例里用到的数据,Vue会修改data里的每个属性的访问控制器属性,当访问每个属性时会访问对应的get方法,修改属性时会执行对应的set方 ...
随机推荐
- 泰山派(Ubuntu 20.0)更换软件源
泰山派更换软件源 1.编辑apt软件包源获取文件 vim /etc/apt/sources.list 2.更换为下面的源 deb http://mirrors.ustc.edu.cn/ubuntu-p ...
- zabbix - [01] 概述
参考:Zabbix教程(Zabbix监控系统精讲) 一.监控介绍 Cacti Cacti 是一套基于PHP.MySQL.SNMP以及RRD Tool开发的监测图形分析工具,Cacti 是使用轮询的方式 ...
- 机器学习 | 强化学习(1) | 马尔科夫决策过程(MDP)概论
最近在搞强化学习(Reinforcement Learning),打算把之前写的笔记整理一下 本文基于大卫 希尔维(David Silver)教授的强化学习概论课程,视频中所采用的样例学生马尔科夫链( ...
- 【Abaqus】Composite Layup建模
abaqus 的3个复合材料建模途径: 传统的material->section->orientation->step->job的建模方式 Composite Layup建模方 ...
- 基于近红外与可见光双目摄像头的人脸识别与活体检测,文末附Demo
基于近红外与可见光双目摄像头的活体人脸检测原理 人脸活体检测(Face Anti-Spoofing)是人脸识别系统中的重要一环,它负责验证捕捉到的人脸是否为真实活体,以抵御各种伪造攻击,如彩色纸张打印 ...
- [Qt基础-06] QButtonGroup
QButtonGroup 本文主要根据QT官方帮助文档以及日常使用,简单的介绍一下QButtonGroup的功能以及基本使用 文章目录 QButtonGroup 简介 信号和槽 简介 有的时候,我们会 ...
- Redis会遇到的15个坑
前言 如果你在使用 Redis 时,也遇到过以下这些「诡异」的场景,那很大概率是踩到「坑」了. 究竟是什么原因,导致的这些问题呢? 我把这些问题划分成了三大部分: 常见命令有哪些坑? 数据持久化有哪些 ...
- IvorySQL 4.2 发布
IvorySQL 4.2 已于 2025 年 1 月 13 日正式发布.新版本全面支持 PostgreSQL 17.2,并修复了多项 bug. 增强功能 PostgreSQL 17.1 增强功能 确保 ...
- 基于RK3568 + FPGA国产平台的多通道AD实时采集显示方案分享
在工业控制与数据采集领域,高精度的AD采集和实时显示至关重要.今天,我们就来基于瑞芯微RK3568J + FPGA国产平台深入探讨以下,它是如何实现该功能的.适用开发环境如下: Windows开发环境 ...
- static修饰成员变量的特点及static修饰成员变量内存图解-java se进阶 day01
1.static介绍 static是静态的意思,它可以用于修饰成员变量和成员方法 2.static的特点 1.被static修饰了的成员变量,可以被类中的所有对象所共享 虽然stu02没有给schoo ...