如何在Vue3中正确使用ref和reactive?
在 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); // 基本类型用refconst data = reactive({ // 复杂对象用reactiveitems: [],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(''), // 基本类型字段用refaddress: reactive({ // 嵌套对象用reactivecity: '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 响应式系统的优势。