浅析vue3中的声明响应式数据 ref 和 reactive

在Vue2中响应式数据是通过defineProperty来实现的,而在Vue3响应式数据是通过ES6的Proxy来实现的。Vue3中实现响应式数据的方法是ref和reactive。

  • defineProperty只能单一地监听已有属性的修改或者变化,无法检测到对象属性的新增或删除,而Proxy可以轻松实现
  •  defineProperty无法监听属性值是数组类型的变化,而Proxy可以轻松实现

 ref注意点

  • 读取任何 ref 对象的值都必须通过 xxx.value
  • 普通变量使用 let 才可以修改值, ref 对象是个引用类型,可以在 const 定义的时候,直接通过 .value 来修改
  • 在数据修改时,可以使用 forEach、map、filter 等遍历函数来操作你的 ref 数组,或者直接重置
  •  如果参数是对象类型,其实底层的本质还是reactive,系统会自动将ref转换为reactive,例如
    ref(1) ===> reactive({value:1})

使用方法:

<template>
	<h1>{
   
   { name }}</h1>
	<h1>{
   
   { age }}</h1>
</template>

<script>
import { ref} from 'vue'
export default {
  name: 'App',
  setup () {
	const name = ref('frank')
	const age = ref(18)
    const handleChange = () => {
		name.value = 'mike'
		age.value = 20
    }
    return { name, age, handleChange }
  }
}
</script>

 reactive注意点

  •  reactive 是继 ref 之后最常用的一个响应式 API 了,相对于 ref,它的局限性在于只适合对象、数组,他能够将复杂数据类型变为响应式数据
  •  reactive的响应式是深层次的,底层本质是将传入的数据转换为Proxy对象
  • 在 vue3中,如果你使用 reactive 定义数组,必须只使用那些不会改变引用地址的操作,不要对通过 reactive 定义的对象进行解构,解构后得到的变量会失去响应性。

失去响应式:

let uids: number[] = reactive([ 1, 2, 3 ]);

// 丢失响应性的步骤
uids = [];

// 异步获取数据后,模板依然是空数组
setTimeout( () => {
  uids.push(1);
}, 1000);

正确方式:

let uids: number[] = reactive([ 1, 2, 3 ]);

// 不会破坏响应性
uids.length = 0;

// 异步获取数据后,模板可以正确的展示
setTimeout( () => {
  uids.push(1);
}, 1000);

 ***ref和reactive***

  • reactive参数一般接受对象或数组,是深层次的响应式。ref参数一般接收简单数据类型,若ref接收对象为参数,本质上会转变为reactive方法
  •  在JS中访问ref的值需要手动添加.value,访问reactive不需要
  •  响应式的底层原理都是Proxy

猜你喜欢

转载自blog.csdn.net/Quentin0823/article/details/126834860