当前观察:【Vuejs】1402- 6 个你必须明白 Vue3 的 ref 和 reactive 问题(入门篇)
Vue3 为开发者提供 ref和 reactive两个 API 来实现响应式数据,这也是我们使用 Vue3 开发项目中经常用到的两个 API。
本文从入门角度和大家介绍这两个 API,如果有错误,欢迎一起讨论学习~
❝「本文演示代码是基于 Vue3 setup 语法。」
❞
【资料图】
在入门阶段,我们需要掌握的是「是什么」、「怎么用」、「有什么注意」,基本就差不多了。
1. reactive API 如何使用?reactive方法用来创建响应式对象,它接收一个对象/数组参数,返回对象的响应式副本,当该对象的属性值发生变化,会自动更新使用该对象的地方。
下面以分别以「对象」和「数组」作为参数演示:
import{reactive}from"vue"letreactiveObj=reactive({name:"Chris1993"});letsetReactiveObj=()=>{reactiveObj.name="HelloChris1993";}letreactiveArr=reactive(["a","b","c","d"]);letsetReactiveArr=()=>{reactiveArr[1]="HelloChris1993";}
模版内容如下:
Vue3reactiveAPIBase
Object:{{reactiveObj.name}}UpdateArray:{{reactiveArr}}Update
此时页面展示如下:
当我们分别点击 Update按钮后,可以看到数据变化后,视图上内容也一起更新了:
2. ref API 如何使用?ref的作用就是将一个「原始数据类型」(primitive data type)转换成一个带有「响应式特性」的数据类型,原始数据类型共有7个,分别是:String/ Number/BigInt/Boolean/Symbol/Null/Undefined。
ref的值在 JS/TS 中读取和修改时,需要使用 .value获取,在模版中读取是,不需要使用 .value。
下面以分别以「字符串」和「对象」作为参数演示:
import{ref}from"vue"letrefValue=ref("Chris1993");letsetRefValue=()=>{refValue.value="HelloChris1993";}letrefObj=ref({name:"Chris1993"});letsetRefObj=()=>{refObj.value.name="HelloChris1993";}
模版内容如下:
Vue3refAPIBase
String:{{refValue}}UpdateObject:{{refObj.name}}Update
此时页面展示如下:
当我们分别点击 Update按钮后,可以看到数据变化后,视图内容也一起更新了:
3. reactive 可以用在深层对象或数组吗?答案是「可以的」,reactive是基于 ES2015 Proxy API 实现的,它的响应式是整个对象的所有嵌套层级。
下面以分别以「对象」和「数组」作为参数演示:
import{reactive}from"vue"letreactiveDeepObj=reactive({user:{name:"Chris1993"}});letsetReactiveDeepObj=()=>{reactiveDeepObj.user.name="HelloChris1993";}letreactiveDeepArr=reactive(["a",["a1","a2","a3"],"c","d"]);letsetReactiveDeepArr=()=>{reactiveDeepArr[1][1]="HelloChris1993";}
模版内容如下:
Vue3reactivedeepAPIBase
Object:{{reactiveDeepObj.user.name}}UpdateArray:{{reactiveDeepArr}}Update
此时页面展示如下:
当我们分别点击 Update按钮后,可以看到数据变化后,视图上内容也一起更新了:
4. reactive 返回值和源对象相等吗?答案是「不相等的」,因为reactive是基于 ES2015 Proxy API 实现的,返回结果是个 proxy 对象。
测试代码:
letreactiveSource={name:"Chris1993"};letreactiveData=reactive(reactiveSource);console.log(reactiveSource===reactiveData);//falseconsole.log(reactiveSource);//{name:"Chris1993"}console.log(reactiveData);//Reactive<{name:"Chris1993"}>5. TypeScript 如何写 ref 和 reactive 参数类型?
在使用 TypeScript 写 ref / reactive 参数类型时,可以根据 ref / reactive 接口类型来实现具体的类型:
functionref(value:T):Ref functionreactive (target:T):UnwrapNestedRefs
将前面实例代码改造一下:
import{ref}from"vue"letrefValue=ref6. 把 ref 值作为 reactive 参数会怎么样?("Chris1993");// refValue 类型为:Ref letsetRefValue=()=>{refValue.value="HelloChris1993";//ok!refValue.value=1993;//error!}//reactive也类似letreactiveValue=reactive<{name:string}>({name:"Chris1993"});
当我们已有一个 ref对象,需要使用在 reactive对象中,会发生什么呢?
假设:
letname=ref("Chris1993");letnameReactive=reactive({name})
我们可以做下列操作:
letname=ref("Chris1993");letnameReactive=reactive({name})console.log(name.value===nameReactive.name);//truename.value="HelloChris1993";console.log(name.value);//HelloChris1993console.log(nameReactive.name);//HelloChris1993nameReactive.name="HiChris1993";console.log(name.value);//HiChris1993console.log(nameReactive.name);//HiChris1993
这是因为 reactive将会对所有深层的 refs进行解包,并且保持 ref的响应式。
当通过赋值方式将 ref分配给 reactive属性时,ref也会自动被解包:
letname=ref("Chris1993");letnameReactive=reactive({})nameReactive.name=name;console.log(name.value);//Chris1993console.log(nameReactive.name);//Chris1993console.log(name.value===nameReactive.name);//true7. 总结
本文主要从入门角度和大家介绍reactive/ ref两个 API 的使用方式区别,还有使用过程中的几个问题。
简单总结一下:
reactive一般用于对象/数组类型的数据,都不需要使用 .value;ref一般用于基础数据类型的数据,在 JS 中读取和修改时,需要使用 .value,在模版中使用时则不需要;reactive可以修改深层属性值,并保持响应;reactive返回值和源对象不同;reactive的属性值可以是 ref值;下一篇将和大家分享精通篇,欢迎大家期待。
相关阅读
-
世界热推荐:今晚7:00直播丨下一个突破...
今晚19:00,Cocos视频号直播马上点击【预约】啦↓↓↓在运营了三年... -
NFT周刊|Magic Eden宣布支持Polygon网...
Block-986在NFT这样的市场,每周都会有相当多项目起起伏伏。在过去... -
环球今亮点!头条观察 | DeFi的兴衰与...
在比特币得到机构关注之后,许多财务专家预测世界将因为加密货币的... -
重新审视合作,体育Crypto的可靠关系才能双赢
Block-987即使在体育Crypto领域,人们的目光仍然集中在FTX上。随着... -
简讯:前端单元测试,更进一步
前端测试@2022如果从2014年Jest的第一个版本发布开始计算,前端开发... -
焦点热讯:刘强东这波操作秀
近日,刘强东发布京东全员信,信中提到:自2023年1月1日起,逐步为...