理解ref和shallowRef的区别

发布时间 2023-11-27 02:14:21作者: 胡安

当使用Vue 3的Composition API时,refshallowRef 都用于创建响应式引用,但它们之间有一些关键的区别。ref 会对其包裹的值进行深层响应式处理,而 shallowRef 则只对其包裹的对象进行浅层响应式处理。

下面是一个示例,说明何时使用 shallowRef 更合适。假设我们有一个包含用户信息的对象,该对象具有以下结构:

const user = {
  id: 1,
  name: 'John Doe',
  address: {
    city: 'New York',
    country: 'USA'
  }
};

现在,我们希望创建一个响应式引用来存储用户信息,并在用户信息发生变化时进行反应。首先,我们使用 ref

import { ref, reactive, watchEffect } from 'vue';

const userData = ref(user);

watchEffect(() => {
  console.log('User data changed:', userData.value);
});

// 修改用户信息
userData.value.name = 'Jane Doe';
userData.value.address.city = 'San Francisco';

在上面的例子中,当我们修改 userData.value.nameuserData.value.address.city 时,watchEffect 将会捕捉到变化。这是因为 ref 对整个对象进行了深层响应式处理。

现在,让我们看看如何使用 shallowRef

import { shallowRef, watchEffect } from 'vue';

const userData = shallowRef(user);

watchEffect(() => {
  console.log('User data changed:', userData.value);
});

// 修改用户信息
userData.value.name = 'Jane Doe'; // 会触发watchEffect
userData.value.address.city = 'San Francisco'; // 不会触发watchEffect

在这个例子中,只有当我们修改 userData.value.name 时,watchEffect 才会被触发,而在修改 userData.value.address.city 时,watchEffect 不会触发。这是因为 shallowRef 只对对象的第一层进行了响应式处理,而不会递归处理嵌套对象。

适合使用 shallowRef 的场景通常是在你只关心对象的顶层属性,而不关心其深层属性的变化时。这可以帮助减少性能开销,因为不必追踪整个对象的变化。