详解vue3中ref和reactive用法和区别

vue3中ref和reactive区别

1、前言

refreactiveVue3中用来实现数据响应式的API,一般情况下,ref定义基本数据类型,reactive定义引用数据类型。

2、基本用法

2.1 ref

  • 理解: ref的参数一般是基本数据类型,也可以是对象类型;如果参数是对象类型,其实底层的本质还是reactive,系统就会自动将ref转换为reactive;我们如果去访问ref定义的值,那么就使用.value的属性去访问定义的数据;ref的底层原理同reactive一样,都是Proxy
  • 语法: const xxx = ref(initValue)

基础用法

javascript 复制代码
<template>
	<h1>{{ name }}</h1>
  	<button @click="changeName">修改名称</button>
</template>

<script setup>
import { ref} from 'vue'
const name = ref('张三')
const changeName = () => {
	name.value = '李四'
	age.value = 20
}
</script>

2.2 reactive

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

基础用法

javascript 复制代码
<template>
	<Child:current="pageConfig.pageNum"></Child>
</template>

<script setup>
import { reactive} from 'vue'
const queryParams= reactive({
	pageNum: 1,
	pageSize: 10
}) 
 
const onChange = () => {
	queryParams.pageNum = 2;
	queryParams.pageSize = 20;
}
</script>

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

javascript 复制代码
const str = reactive('字符串')

3、ref和reactive定义数组对比

3.1 ref定义数组

javascript 复制代码
<template>
	<Table :data="tableData"></Table>
</template>

<script setup>
import { ref, reactive, onMounted } from 'vue'
import { getTableDataApi } from '@/api'
const queryParams= reactive({
	pageNum: 1,
	pageSize: 10
}) 
 
const tableData = ref([]) 
onMounted(() => {
	getTableData()
})
const getTableData = async () => {
	const { data } = await getTableDataApi(queryParams) // 模拟接口获取表格数据
	tableData.value = data 
}
</script>

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

3.1 reactive定义数组

javascript 复制代码
<template>
	<Table :data="tableData"></Table>
</template>

<script setup>
import { ref, reactive, onMounted } from 'vue'
import { getTableDataApi } from '@/api'
const queryParams= reactive({
	pageNum: 1,
	pageSize: 10
}) 
 
const tableData = reactive([]) 
onMounted(() => {
	getTableData()
})
const getTableData = async () => {
	const { data } = await getTableDataApi(queryParams) // 模拟接口获取表格数据
	tableData= data 
}
</script>

需要注意的是,reactive定义的数组使用 tableData = data 的修改方式会造成 tableData 响应式丢失。

解决方法如下:

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

4、ref 和reactive的区别

  1. ref用于定义基本类型和引用类型,reactive仅用于定义引用类型;
  2. reactive只能用于定义引用数据类型的原因在于内部是通过ES6的Proxy实现响应式的,而Proxy不适用于基本数据类型;
  3. ref定义对象时,底层会通过reactive转换成具有深层次的响应式对象,所以ref本质上是reactive的再封装;
  4. 在JS中我们如果去对数据进行操作,在ref定义的数据中,使用变量.value;访问reactive不需要;
  5. 在定义数组时,建议使用ref,从而可避免reactive定义时值修改导致的响应式丢失问题。
相关推荐
共享家95273 小时前
搭建 AI 聊天机器人:”我的人生我做主“
前端·javascript·css·python·pycharm·html·状态模式
摘星编程5 小时前
OpenHarmony环境下React Native:自定义useTruncate文本截断
javascript·react native·react.js
Duang007_5 小时前
【LeetCodeHot100 超详细Agent启发版本】字母异位词分组 (Group Anagrams)
开发语言·javascript·人工智能·python
有来技术6 小时前
Spring Boot 4 + Vue3 企业级多租户 SaaS:从共享 Schema 架构到商业化套餐设计
java·vue.js·spring boot·后端
东东5167 小时前
学院个人信息管理系统 (springboot+vue)
vue.js·spring boot·后端·个人开发·毕设
2601_949868367 小时前
Flutter for OpenHarmony 电子合同签署App实战 - 主入口实现
开发语言·javascript·flutter
m0_748229997 小时前
Vue2 vs Vue3:核心差异全解析
前端·javascript·vue.js
xiaoxue..7 小时前
React 手写实现的 KeepAlive 组件
前端·javascript·react.js·面试
摘星编程7 小时前
在OpenHarmony上用React Native:自定义useHighlight关键词高亮
javascript·react native·react.js
2601_949613029 小时前
flutter_for_openharmony家庭药箱管理app实战+用药知识详情实现
android·javascript·flutter