在 Vue3 中正确使用 ref
和 reactive
需要根据场景选择合适的方式,以下是核心要点:
1. 基础使用场景
(1)ref
适用情况
- 基本类型数据(字符串/数字/布尔值)
- 需要重新赋值的对象引用
- 模板中自动解包(无需
.value
)
const count = ref(0); // 基本类型
const user = ref({ name: 'Alice' }); // 对象类型
(2)reactive
适用情况
- 复杂对象/数组(嵌套结构)
- 不需要整体替换的对象
- 需要直接修改属性的场景
<template>
<div>实际参数{{msgObj.content}}</div>
<div>
<button @click="handleClick">点击</button>
</div>
</template>
<script setup lang="ts">
import {reactive,ref} from "vue";
interface MsgObj {
content: String
}
const msgObj:MsgObj = reactive({content: ref('hi! js')})
function handleClick () {
msgObj.content += ' yes'
}
</script>
2. 关键差异对比
特性 | ref |
reactive |
---|---|---|
数据访问 | 脚本中需 .value |
直接访问属性 |
响应性保持 | 解构后仍响应 | 需配合 toRefs 保持响应性 |
重新赋值 | 支持(.value = newValue ) |
需用 Object.assign 合并 |
3. 混合使用最佳实践
(1)组合式函数封装
function useFeature() {
const loading = ref(false); // 基本类型用ref
const data = reactive({ // 复杂对象用reactive
items: [],
pagination: { page: 1 }
});
const fetchData = async () => {
loading.value = true;
// 请求逻辑...
Object.assign(data.pagination, res.pagination); // 合并更新
};
return { loading, ...toRefs(data), fetchData }; // 返回解构响应数据
}
(2)表单处理示例
const form = reactive({
name: ref(''), // 基本类型字段用ref
address: reactive({ // 嵌套对象用reactive
city: 'Beijing',
street: ''
})
});
4. 常见问题解决方案
reactive
解构丢失响应性:const state = reactive({ count: 0 }); const { count } = toRefs(state); // 保持响应
模板中自动解包:
<template> {{ count }} <!-- ref自动解包 --> {{ state.list }} <!-- reactive直接访问 --> </template>
类型提示(TS):
const count = ref<number>(0); // 显式泛型 interface State { list: string[]; } const state = reactive<State>({ list: [] });
5. 选择建议
- 优先
ref
:基本类型、需要重新赋值的变量 - 优先
reactive
:复杂对象、表单嵌套结构 - 避免混用:同一数据源不要同时使用两种方式
通过合理组合使用,可以充分发挥 Vue3 响应式系统的优势。