Vue3中的toRef,toRefs,toRaw
以下是关于 Vue3 中 toRef
、toRefs
和 toRaw
的详细教程及使用实例:
一、toRef
:创建单个属性的响应式引用
作用
将响应式对象的单个属性转换为 ref
对象,保持与原始属性的响应式连接。修改 ref
值会同步更新原对象,反之亦然。
使用场景
- 需要单独操作对象的某个属性时
- 传递单个属性到子组件时保持响应性
示例代码
import { reactive, toRef } from 'vue';
const state = reactive({ name: 'Alice', age: 25 });
const nameRef = toRef(state, 'name'); // 将 name 转换为 ref
// 修改 ref 值
nameRef.value = 'Bob';
console.log(state.name); // 输出 'Bob'(原对象同步更新)
二、toRefs
:批量解构响应式对象
作用
将整个响应式对象的所有属性转换为普通对象,每个属性都是 ref
引用,避免解构时丢失响应性。
使用场景
- 解构
reactive
对象后仍需保持响应性 - 在组合式函数中返回多个响应式属性
示例代码
import { reactive, toRefs } from 'vue';
const state = reactive({ count: 0, message: 'Hello' });
const { count, message } = toRefs(state); // 解构后仍为 ref
// 修改 ref 值
count.value++;
message.value = 'Bonjour';
console.log(state.count); // 输出 1(原对象同步更新)
对比直接解构
// ❌ 错误示例:直接解构会失去响应性
const { count } = state;
count++; // 视图不会更新
// ✅ 正确示例:使用 toRefs
const { count } = toRefs(state);
count.value++; // 视图更新
三、toRaw
:获取原始非代理对象
作用
返回响应式对象(reactive
或 readonly
创建)的原始非代理版本,修改原始对象不会触发视图更新。
使用场景
- 需要对比原始数据时
- 与第三方库交互时避免代理干扰
示例代码
import { reactive, toRaw } from 'vue';
const state = reactive({ data: 'secret' });
const rawState = toRaw(state); // 获取原始对象
// 修改原始对象
rawState.data = 'modified';
console.log(state.data); // 输出 'modified'(响应式对象的值变化)
console.log(rawState === state); // 输出 false(非同一对象)
四、综合对比与注意事项
方法 | 输入类型 | 输出类型 | 响应式保持 | 典型场景 |
---|---|---|---|---|
toRef |
响应式对象 + 属性 | ref |
✔️ | 单独操作属性 |
toRefs |
响应式对象 | 普通对象(含 ref) | ✔️ | 解构对象或组合式函数返回值 |
toRaw |
响应式对象 | 原始对象 | ❌ | 数据对比、避免副作用 |
注意事项
- 非响应式对象:若对普通对象使用
toRef
/toRefs
,修改ref
不会更新视图,但数据会变化。 - 性能优化:
toRaw
可用于处理大型数据,跳过代理转换提升性能。 - 深层响应性:
toRefs
仅处理对象的第一层属性,嵌套对象需手动处理。
五、完整实例演示
<template>
<div>
<p>Name: {{ nameRef }}</p>
<p>Count: {{ count }}</p>
<button @click="modifyData">修改数据</button>
</div>
</template>
<script setup>
import { reactive, toRef, toRefs, toRaw } from 'vue';
const state = reactive({
name: 'Vue3',
count: 0,
nested: { key: 'value' }
});
// 使用 toRef
const nameRef = toRef(state, 'name');
// 使用 toRefs
const { count } = toRefs(state);
// 使用 toRaw
const modifyData = () => {
const raw = toRaw(state);
raw.nested.key = 'newValue'; // 修改原始对象,不会触发视图更新
console.log(raw === state); // false
};
</script>
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 万家灯火