Vue.js 中 ref 和 reactive 的区别及用法
ref
-
目的:创建一个对值的响应式引用。
-
用法:通过
.value属性来访问和修改值。 -
示例:
import { ref } from 'vue';const count = ref(0);count.value++; // 增加值
console.log(count.value); // 访问值
-
直接赋值数组:
ref创建的是一个包含.value属性的对象,这个.value属性持有实际的数据。无论如何改变这个.value的内容,Vue 都能检测到变化并进行更新。
import { ref } from 'vue';const city1List = ref([]);onMounted(() => {getCityByPid(0).then(res => {city1List.value = res.data.data; // 直接赋值新数组console.log(city1List.value); // 访问数组内容});
});
reactive
-
目的:创建一个深度响应的对象或数组。
-
用法:直接修改响应对象或数组的属性。
-
示例:
import { reactive } from 'vue'; const state = reactive({ count: 0 }); state.count++; // 增加 count console.log(state.count); // 访问 count -
不能直接赋值数组:
reactive创建的是一个深度响应的对象或数组,Vue 只跟踪创建时的对象引用。如果直接重新赋值一个新的对象或数组,Vue 将无法跟踪新的引用,因为新的引用不会被自动转换为响应式对象。import { reactive } from 'vue'; let city1List = reactive([]); onMounted(() => { getCityByPid(0).then(res => { city1List.splice(0, city1List.length, ...res.data.data); // 使用数组方法修改内容 console.log(city1List); // 访问数组内容 }); );
关键区别和最佳实践
-
ref:- 创建一个响应式引用。
- 使用
.value来访问和修改值。 - 可以直接通过
.value重新赋值新的数组或对象。
-
reactive:- 创建一个深度响应的对象或数组。
- 直接修改对象或数组的属性或元素。
- 不能直接重新赋值整个对象或数组,而需要修改其内部的属性或元素。
实际解决方案
使用 reactive 更新数组时,可以使用 splice 清除并替换元素,这样保持了对原始响应数组的引用,Vue 会继续跟踪其内容的变化。
import { reactive } from 'vue';let city1List = reactive([]);onMounted(() => {getCityByPid(0).then(res => {city1List.splice(0, city1List.length, ...res.data.data); // 清除现有数组并添加新项目console.log(city1List); // 访问数组内容});
});
总结
ref适用于需要频繁更改整个值的场景,因为它可以直接赋值新的数组或对象。reactive适用于需要深度响应的对象或数组,在修改其内部属性或元素时能保持响应性。