ref和reactive都是Vue3中的响应式数据类型,它们的区别在于:
- ref是一种轻量级的响应式数据类型,它只能用于基本类型和对象类型,而不能用于数组类型。使用ref时,需要通过.value属性来访问和修改它的值。
import { ref } from 'vue'
const count = ref(0)
console.log(count.value) // 输出 0
count.value++ // count.value现在是1
- reactive是一种更强大的响应式数据类型,它可以用于任意类型的数据,包括数组、对象、函数等。使用reactive时,不需要通过.value属性来访问和修改它的值。
import { reactive } from 'vue'
const state = reactive({ count: 0 })
console.log(state.count) // 输出 0
state.count++ // state.count现在是1
需要特别注意的是:在Vue3中,reactive创建的响应式对象会被新赋值的直接代理,导致reactive创建的响应式对象丢失响应式。这是因为每次直接把一个对象或者数组赋值给reactive创建的对象或数组时,会导致reactive创建的响应式对象被新赋值的直接代理。
在Vue3中,reactive创建的响应式对象会被新赋值的直接代理,导致reactive创建的响应式对象丢失响应式。以下是一些案例:
- 直接赋值:当你定义了一个数据并使用reactive进行处理后,如果你直接把一个新的对象或数组赋值给这个数据,那么这个数据就会失去响应式。例如:
import { reactive } from 'vue'
const state = reactive({ count: 0 })
state.count = 1 // 这样写会导致state.count变成普通变量,而不是响应式数据
- 修改嵌套对象:如果你修改了一个嵌套对象中的一个属性,那么由于Vue3中的响应式系统只能检测到根级别的属性变化,所以嵌套对象中的属性变化不会被检测到,从而导致嵌套对象失去响应式。例如:
import { reactive } from 'vue'
const state = reactive({ user: { name: '张三', age: 18 } })
state.user.age = 20 // 这样写会导致state.user.age变成普通变量,而不是响应式数据
- 修改数组长度:如果你修改了一个数组的长度,那么由于Vue3中的响应式系统只能检测到根级别的属性变化,所以数组中的元素变化不会被检测到,从而导致数组失去响应式。例如:
import { reactive } from 'vue'
const state = reactive([])
state.push(1) // 这样写会导致state变成一个普通数组,而不是响应式数组