在 Vue 3 中,提供了多种创建响应式数据的方法,下面将详细介绍这些方法及其使用场景。
reactive 函数
reactive 函数用于创建一个响应式对象。它接收一个普通对象作为参数,并返回一个响应式的代理对象。
示例代码
<template>
  <div>
    <p>{{ state.count }}</p>
    <button @click="increment">增加</button>
  </div>
</template>
<script setup>
import { reactive } from 'vue';
const state = reactive({
  count: 0
});
const increment = () => {
  state.count++;
};
</script>
解释: reactive 函数将一个普通对象转换为响应式对象。当修改 state 对象的属性时,Vue 会自动更新与之绑定的 DOM。
ref 函数
ref 函数用于创建一个响应式的引用。它可以用于包装基本数据类型(如 number、string、boolean 等),也可以用于包装对象。
示例代码
<template>
  <div>
    <p>{{ count.value }}</p>
    <button @click="increment">增加</button>
  </div>
</template>
<script setup>
import { ref } from 'vue';
const count = ref(0);
const increment = () => {
  count.value++;
};
</script>
解释: ref 函数创建一个包含响应式数据的对象,该对象有一个 .value 属性用于访问和修改数据。在模板中使用 ref 时,不需要使用 .value,Vue 会自动解包。
toRef 和 toRefs 函数
toRef 用于从一个响应式对象中创建一个单独的响应式引用。
示例代码
<template>
  <div>
    <p>{{ countRef.value }}</p>
    <button @click="increment">增加</button>
  </div>
</template>
<script setup>
import { reactive, toRef } from 'vue';
const state = reactive({
  count: 0
});
const countRef = toRef(state, 'count');
const increment = () => {
  countRef.value++;
};
</script>
解释: toRef 创建的引用与原对象的属性保持响应式连接。
toRefs 用于将一个响应式对象转换为普通对象,其中每个属性都是一个 ref。
示例代码
<template>
  <div>
    <p>{{ count }}</p>
    <button @click="increment">增加</button>
  </div>
</template>
<script setup>
import { reactive, toRefs } from 'vue';
const state = reactive({
  count: 0
});
const { count } = toRefs(state);
const increment = () => {
  count.value++;
};
</script>
解释: toRefs 常用于解构响应式对象,以保持响应式连接。
shallowReactive 和 shallowRef 函数
shallowReactive 只对对象的第一层属性进行响应式处理,而不会递归处理嵌套对象。
示例代码
<template>
  <div>
    <p>{{ state.name }}</p>
    <p>{{ state.info.address }}</p>
    <button @click="changeName">修改姓名</button>
    <button @click="changeAddress">修改地址</button>
  </div>
</template>
<script setup>
import { shallowReactive } from 'vue';
const state = shallowReactive({
  name: '张三',
  info: {
    address: '北京市'
  }
});
const changeName = () => {
  state.name = '李四';
};
const changeAddress = () => {
  state.info.address = '上海市';
};
</script>
解释: 修改 state.name 会触发响应式更新,但修改 state.info.address 不会。
shallowRef 只对 .value 属性进行响应式处理,而不会对其内部对象进行递归处理。
示例代码
<template>
  <div>
    <p>{{ state.value.name }}</p>
    <button @click="changeName">修改姓名</button>
  </div>
</template>
<script setup>
import { shallowRef } from 'vue';
const state = shallowRef({
  name: '张三'
});
const changeName = () => {
  // 这样不会触发响应式更新
  // state.value.name = '李四';
  // 需要替换整个 .value 对象
  state.value = {
    ...state.value,
    name: '李四'
  };
};
</script>
解释: 直接修改 state.value 的属性不会触发响应式更新,需要替换整个 .value 对象。
以上就是 Vue 3 中常用的创建响应式数据的方法,你可以根据具体的需求选择合适的方法