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方 ...
随机推荐
- 前端跨域方案-跨域请求代理(asp.net handler)
现在技术开发偏向于使用统一的接口处理浏览器或者app的http请求. 大家都知道因为浏览器的同源策略的原因 js直接请求webapi 接口会有一些问题,即使做好服务器端的配置 同样会有不少的 问题 ...
- 【Abaqus】Composite Layup建模
abaqus 的3个复合材料建模途径: 传统的material->section->orientation->step->job的建模方式 Composite Layup建模方 ...
- 《空间三角面片对相交判断算法》的matlab实现_ 0.2微秒
function [flag] = InsectTriPatch(T1,T2) % 判断两个空间三角形面片是否相交 % T1=[0 0 0; % 2 0 0; % 0 1.5 0; % 0 0 1]; ...
- wxformbuilder 如何生成python 代码
?问题 正常通过F8->F6 ,我执行这两步操作后如下图,以.fbp格式显示,没生成文件 解决方案 object properties 下勾选python 效果图:
- AWVS安装使用
AWVS安装使用 1.双击exe文件,然后点击下一步. 2.选择我接受,然后下一步. 3.选择路径(我选择的默认路径)然后下一步. 4.还是下一步. 5.设置邮箱,用户名密码,用户名12345678@ ...
- vuex 踩坑记之unknown local mutation type
使用模块化定义vuex时,出现了这么个错误unknown local mutation type,检查好久发现单词并没有写错,代码如下: // 引入请求数据的方法 import { reqUsers ...
- 【vscode】vscode配置汇编环境
[vscode]vscode配置汇编环境 前言 因为近来个人的课程涉及到汇编语言,加上个人目前是个vscode的重度使用者,所以,要捣鼓一下汇编的配置. 自然,有很多博客写过如何配置,但是每个人在 ...
- PaddleOCR学习笔记2-初步识别服务
今天初步实现了网页,上传图片,识别显示结果到页面的服务.后续再完善. 采用flask + paddleocr+ bootstrap快速搭建OCR识别服务. 代码结构如下: 模板页面代码文件如下: up ...
- Linux-两台Linux服务器间设置共享文件夹(NFS服务器)
一.环境信息服务器1:192.168.120.141 文件夹:/opt服务器2:192.168.120.142 文件夹:/opt将服务器1的/opt文件夹共享到服务器2的/ ...
- 记录一个命令 可以在linux很方便的安装一些软件
小鱼的一键安装系列 wget http://fishros.com/install -O fishros && . fishros 一键安装:ROS(支持ROS和ROS2,树莓派Jet ...