详解Vue3.0中 ref、reactive、toRef、toRefs 四个核心API函数作用及使用场景

        最近刚学习完了 Vue3.0,V3在响应式数据的声明上不再使用原来的选项式 data 进行 retuan 返回的形式,取而代之的是通过变量修饰符使用 ref、reactive 进行手动声明的方式。相较于 Vue2.0 确实是更加灵活了许多,Vue3.0(以下简称V3)中进行响应式数据操作会使用 ref、reactive、toRef、toRefs四个核心 API 函数,那么今天就从解析以下其各个作用及其使用场景。

ref

         首当其冲讲的自然是我们的 ref 函数,它的最简单使用方式如下:

<template>
	<div>
		<p>名字: {
   
   {name}}</p>
		<button @click="alterName">修改名字为李四</button>
	</div>
</template>

<script setup>
	import {ref} from "vue";
	let name = ref("张三");
	const alterName = () => {
		name.value = "李四";
	}
</script>

        ref 通常用于将基本数据类型(String、Number、Boolean...)转为响应式的,也可以将引用数据类型转为响应式的、但引用数据类型我们通常会使用 reactive 进行声明。而操作 ref 声明的数据无论基本或引用数据类型都需要需要通过 .value 的方式进行(模板中不需要),那我们可以模拟看看 ref 函数的内部代码:

function ref(params){
	const data = {value: params};
	return new Proxy(data,{
		get(){},
		set(){}
	})
}

        也就是说,无论使用 ref 函数转的数据是什么,都会被再嵌套一层 value 属性的对象,所以我们通常使用它将基本数据类型转换为响应式的。

reactive

        再看 reactive,它的最基本使用方式如下:

<template>
	<div>
		<p>{
   
   { data.name }}今年{
   
   {data.age}}岁了</p>
		<p>{
   
   { arr }}</p>
		<button @click="alterArr">修改数组内容</button>
	</div>
</template>

<script setup>
	import { reactive } from "vue";
	let data = reactive({
		name: "张三",
		age: "18"
	});
	let arr = reactive([1, 2, 3, 4, 5]);
	const alterArr = () => {
		arr.length = 0
		arr.push(...[1, 1, 1, 1, 1]);
	}
</script>

        以上可以看到,对于修改响应式数组 arr 的整体数据时,先通过 length 设置数组长度为 0 后再去添加新内容才能继续保持响应式,而不是直接赋值,即使使用以下方式却不能保持响应式。

arr = reactive([1,1,1,1,1,]);

reactive 无法将基本数据类型转换为 响应式对象,这可能源于其内部机制,如下:

function reactive(params){
    // 判断是否是 object 对象
	if(params instanceof Object) return params;
	return new Proxy(params, {
		get(){},
		set(){}
	})
}

toRef

        toRef可以从原来的响应式数据上拷贝一份新的响应式对象,修改新的响应式对象时也会影响到老的响应式对象,类似于浅拷贝。下面是使用场景:

<template>
	<div>
		<p>arr内容: {
   
   { arr }}</p>
		<p>arrCopy内容: {
   
   { arrCopy }}</p>
		<button @click="alterArrCopy">修改数组内容</button>
	</div>
</template>

<script setup>
	import {
		reactive,
		toRef
	} from "vue";
	
	let data = reactive({
		name: "张三",
		age: "18"
	});
	
	let arr = reactive([1, 2, 3, 4, 5]);
	
	let arrCopy = toRef(arr)._object;
	let objs = {arrCopy}
	
	const alterArrCopy = () => {
		objs.arrCopy[1] = "我改变了"; // == || arrCopy[1] = "我改变了"
	}
</script>

 或

<template>
	<div>
		<p>dataCopy内容: {
   
   { dataCopy }}</p>
		<button @click="alterArrCopy">修改数组内容</button>
	</div>
</template>

<script setup>
	import {
		reactive,
		toRef
	} from "vue";

	let data = reactive({
		name: "张三",
		age: "18"
	});
	let dataCopy = toRef(data, "name");
	let objs = {
		dataCopy
	}
	const alterArrCopy = () => {
		dataCopy.value = "我改变了";
		// 或
		// objs.Copy.value = "我改变了";
	}
</script>

toRefs

         toRefs 可以将 reactive 创建的响应式对象转换为一个个通过 .value 获取值 ref 对象, 通常可以用在 ES6 结构赋值中,当一个响应式数据属性被直接解构时,解构出来的值不会与源对象保持响应式连接,当使用 toRefs 后就可以与源数据保持响应式连接。

<template>
	<div>
		<p>data内容: {
   
   { data }}</p>
		<p>{
   
   { name  }} {
   
   { age }}</p>
		<button @click="alterData">修改对象内容</button>
	</div>
</template>

<script setup>
	import {
		reactive,
		toRefs
	} from "vue";

	let data = reactive({
		name: "张三",
		age: "18"
	});
    
    const obj = toRefs(data);
	const { name, age } = toRefs(data);

	const alterData = () => {
        // obj.name.value = "李四" // 和下面作用相同
		name.value = "李四"; // data 的 name 属性也会发生变化
	}
</script>

        希望能够有所帮助! 

猜你喜欢

转载自blog.csdn.net/weixin_60678263/article/details/129055923