首页 > 其他分享 >谈谈Vue3中的ref和reactive

谈谈Vue3中的ref和reactive

时间:2023-06-19 17:23:16浏览次数:46  
标签:const 定义 data reactive Vue3 ref tableData

谈谈Vue3中的ref和reactive

ref和reactive是什么?
ref和reactive是Vue3中用来实现数据响应式的API
一般情况下,ref定义基本数据类型,reactive定义引用数据类型
(我喜欢用它来定义对象,不用它定义数组,原因后面讲)
我理解的ref本质上是reactive的再封装

二、先聊reactive
reactive定义引用数据类型(以对象和数组举例),它能够将复杂数据类型的内部属性或者数据项声明为响应式数据,所以reactive的响应式是深层次的,其底层是通过ES6的Proxy来实现数据响应式,相对于Vue2的Object.defineProperty,具有能监听增删操作,能监听对象属性的变化等优点

使用reactive定义对象数据类型举例

const paginationConfig = reactive({
pageNum: 1,
pageSize: 10
}) // 定义

const onChange = () => {
paginationConfig.pageNum = 2 // js使用
paginationConfig.pageSize = 20 // js使用
}
<!-- Vue3模板引用使用 -->

<a-pagination v-model:current="paginationConfig.pageNum"></a-pagination>

若用reactive定义基本数据类型,Vue3会报警告错误,如图

const str = reactive('我是字符串')

 

分析Vue3源码可知,使用reactive定义响应式数据时,若数据不是对象类型直接就返回了,就不会进行后续的数据响应式处理了,这也就是我只用reactive定义对象型响应式数据的原因,那数组类型数据怎么办呢?答案在下文中可以找到

 

三、再聊ref

为什么我会理解成ref是reactive的再封装,因为在ref的底层源码里最终还是reactive()来实现的

 

 

 由源码分析得知,如果是对象类型,底层走的还是reactive()的逻辑,另外我们知道,使用ref定义基本数据类型时,在脚本里使用时,需要加.value后缀,然而在模板里不需要,这是因为Vue3会自动帮你加上,这就使得ref相比reactive更加简单

let num = ref(0)// 定义

let isShow = ref(false) // 定义

const onChange = () => {

num.value++ // js使用

isShow.value = true // js使用

}

<!-- Vue3模板引用使用 --> <a-modal v-model:visible="isShow"></a-modal>

四、ref和reactive定义数组对比

使用ref定义数组举例如下

const tableData = ref([]) // 定义

const getTableData = async () => {
const { data } = await getTableDataApi() // 模拟接口获取表格数据
tableData.value = data // 修改
}

<!-- Vue3模板引用使用 -->

<a-table v-model:dataSource="tableData"></a-table>

图中以我们常用的表格数据举例,可以看到,ref定义数组与定义基本数据类型没什么差别,接下来看看reactive

const tableData = reactive([]) // 定义

const getTableData = async () => {
const { data } = await getTableDataApi() // 模拟接口获取表格数据
tableData = data // 修改,错误示例,这样赋值会使tableData失去响应式
}
<!-- Vue3模板引用使用 -->

<a-table v-model:dataSource="tableData"></a-table>

需要注意的是,使用 tableData = data 的修改方式会造成 tableData 响应式丢失,解决方法如下(供参考)

// 方法一:改为 ref 定义
const tableData = ref([])
const getTableData = async () => {
const { data } = await getTableDataApi()
tableData.value = data // 使用.value重新赋值
}
// 方法二:使用 push 方法
const tableData = reactive([])
const getTableData = async () => {
const { data } = await getTableDataApi()
tableData.push(...data) // 先使用...将data解构,再使用push方法
}
// 方法三:定义时数组外层嵌套一个对象
const tableData = reactive({ list:[] })
const getTableData = async () => {
const { data } = await getTableDataApi()
tableData.list = data // 通过访问list属性重新赋值
}
// 方法四:赋值前再包一层 reactive
const tableData = reactive([])
const getTableData = async () => {
const { data } = await getTableDataApi()
tableData = reactive(data) // 赋值前再包一层reactive
}

五、对比总结
1.ref用于定义基本类型和引用类型,reactive仅用于定义引用类型
2.reactive只能用于定义引用数据类型的原因在于内部是通过ES6的Proxy实现响应式的,而Proxy不适用于基本数据类型
3.ref定义对象时,底层会通过reactive转换成具有深层次的响应式对象,所以ref本质上是reactive的再封装
4.在脚本里使用ref定义的数据时,记得加.value后缀
5.在定义数组时,建议使用ref,从而可避免reactive定义时值修改导致的响应式丢失问题


原文链接:https://blog.csdn.net/poppingJ/article/details/125429506

标签:const,定义,data,reactive,Vue3,ref,tableData
From: https://www.cnblogs.com/Dasate/p/17491629.html

相关文章

  • vite+vue3项目中使用 lottie 动画,如何在 template 中直接使用本地 json 文件路径
    安装lottie-webyarnaddlottie-web封装 lottie组件<template><divref="animation":style="{width,height}"></div></template><script>import{defineComponent,ref,onMounted}from'vue'......
  • Understanding JavaScript Garbage Collection: Dive into Reference Counting and Ma
    JavaScript,theprogramminglanguageoftheweb,isoftenpraisedforitsabilitytohandlememorymanagementautomatically.TheJavaScriptengine'sgarbagecollectorplaysapivotalroleinthisprocess.Today,we'lltakeadeepdiveintotwom......
  • 手动刷新refresh
    refresh1.es数据写入的流程对于任何数据库的写入来讲fsync刷盘虽然保证的数据的安全但是如果每次操作都必须fsync一次,那fsync操作将是一个巨大的操作代价,在衡量对数据安全与操作代价下,ES引入了一个较轻量的操作refresh操作来避免频繁的fsync操作。2.什么是refresh写入documen......
  • Vue3 - 实现文本复制粘贴功能
    1.安装库并导入npmivue-clipboard3--save2.在需要的前端文件中导入importclipboard3from'vue-clipboard3'html结构如下<template><divclass="hello"><inputtype="text"v-model="text"><button@cli......
  • ref属性
    <!--ref属性1.被用来给元素或子组件注册引用信息(id的替代者)2.应用在html标签上获取的是真实的DOM元素,应用在组件标签上是组件实例对象--><template><divid="app"><h2v-text="msg"ref="title"hh="哈哈"></h2><button@cli......
  • 一文看完Vue3的渲染过程
    Vue3官网中有下面这样一张图,基本展现出了Vue3的渲染原理:本文会从源码角度来草率的看一下Vue3的运行全流程,旨在加深对上图的理解,从下面这个很简单的使用示例开始:import{createApp,ref}from"vue";createApp({template:`<divclass="card"><butt......
  • Reactive Extensions 响应式扩展 用于事件驱动编程的库,具有可组合的声明性模型
    响应式扩展这个存储库包含四个库,它们在概念上是相关的,因为它们都与LINQoverofthings序列有关:ReactiveExtensionsfor.NET又名Rx.NET或Rx( System.Reactive ):一个用于事件驱动编程的库,具有可组合的声明性模型AsyncRx.NET(实验性预览)(System.Reactive.Async):Rx的实验......
  • vue3+vite+web3.js报错ReferenceError: process is not defined
    在vite最新版本中使用web3会报错只需要在vite.config.ts添加如下代码即可解决报错import{fileURLToPath,URL}from'node:url'import{defineConfig}from'vite'importvuefrom'@vitejs/plugin-vue'//引入import{resolve}from'path'export......
  • vue3Props
    一、Props声明一个组件需要显式声明它所接受的props,这样Vue才能知道外部传入的哪些是props,哪些是透传 attribute在使用SFC时,props可以使用defineProps()宏来声明:如子组件中(1)constprops=defineProps(['foo'])(2)constprops=defineProps({ title:String, age......
  • Cannot Reference “XxxClass.xxxmember” Before Supertype Constructor Has Been Ca
    在调用超类型构造函数之前无法引用“XxxClass.xxx”-----在一个类的构造器方法还未执行的时候,我们无法使用这个类的成员属性或成员方法。百度翻译:在调用超类型构造函数之前无法引用“XxxClass.xxx”-----我的理解:在一个类的构造器方法还未执行的时候,我们......