当前位置: 首页 > article >正文

Vue 3 中 toRaw 的详细讲解

toRaw 是 Vue 3 提供的一个  API,主要用于从 Vue 的响应式对象中获取其对应的原始非响应式对象。

1. toRaw 的作用

1、获取原始对象

当对象被 Vue 的响应式系统包裹时,直接访问它会返回一个 Proxy 对象。如果需要访问未被响应式系统代理的原始对象,可以使用 toRaw。

2、调试辅助

在调试时,如果响应式对象出现了意料之外的行为,toRaw 可以帮助我们查看原始数据。

3、与第三方库兼容

某些第三方库不支持 Vue 的响应式对象(Proxy 对象),这时可以通过 toRaw 将响应式对象转为普通对象传递给它们。

2. toRaw 的用法

2.1 基本语法
import { reactive, toRaw } from 'vue';

const reactiveObj = reactive({ foo: 'bar' });
const rawObj = toRaw(reactiveObj);

console.log(reactiveObj); // Proxy {foo: "bar"}
console.log(rawObj); // {foo: "bar"}
2.2 使用场景

1、获取原始对象进行对比或操作

响应式对象中的 Proxy 包裹可能会导致意外行为,比如在比较对象时。

import { reactive, toRaw } from 'vue';
const reactiveObj = reactive({ a: 1 });
const rawObj = toRaw(reactiveObj);
// 比较原始对象
console.log(rawObj === reactiveObj); // false
console.log(rawObj == { a: 1 }); // false
// 使用原始对象
const anotherObj = { ...rawObj }; // 拷贝原始对象
console.log(anotherObj); // { a: 1 }

2、Debug 或日志记录

为了避免调试时输出 Proxy 对象,可以用 toRaw 获取原始数据。

import { reactive, toRaw } from 'vue';
const state = reactive({ count: 0 });
function logState() {
  console.log('State:', toRaw(state));
}
state.count++;
logState(); // 输出:State: { count: 1 }

3、防止无限递归更新

在某些情况下(如递归处理响应式对象),直接操作响应式数据可能会导致不必要的额外开销或无限递归,使用 toRaw 可以避免这些问题。

import { reactive, toRaw } from 'vue';
const data = reactive({ nested: { value: 1 } });
function process(obj) {
  const raw = toRaw(obj); // 获取原始对象
  console.log(raw); // { value: 1 }
}
process(data.nested);

3. 注意事项

1、toRaw 不会脱离响应式系统

使用 toRaw 获取原始对象后,对原始对象的修改不会触发 Vue 的响应式更新,但对原始对象的修改仍会触发更新。

🌰

<template>
  <div>obj.foo: {{ obj.foo }}</div>
</template>
<script setup>
import { reactive, toRaw } from 'vue'
const obj = reactive({ foo: '更新前数据 hello' })
const raw = toRaw(obj)

setTimeout(() => {
  raw.foo = '更新后数据 hi'
  console.log('obj.foo', obj.foo) // "更新后数据 hi"(原始对象和响应式对象指向同一内存地址)
})
</script>

2、 不要滥用 toRaw 

-  toRaw 应用于特定场景,如与第三方库交互或调试时。一般情况下,应尽量使用响应式数据。

- 滥用 toRaw 可能破坏 Vue 的响应式系统,导致不可预测的行为。

3、原始对象不能被 reactive 再次代理

如果对原始对象应用 reactive,Vue 会返回其原始的响应式对象,而不是重新代理它。

🌰

import { reactive, toRaw } from 'vue'
const obj = reactive({ foo: 'bar' })
const raw = toRaw(obj)
const newReactive = reactive(raw)
console.log(newReactive === obj) // true

4、只对响应式对象有效

如果传入的不是响应式对象,toRaw 会直接返回原对象。

import { toRaw } from 'vue'
const plainObj = { foo: 'bar' }
console.log(toRaw(plainObj) === plainObj) // true

完整示例 🌰

import { defineComponent, reactive, toRaw } from 'vue';

export default defineComponent({
  setup() {
    const state = reactive({
      items: [
        { id: 1, name: 'Vue' },
        { id: 2, name: 'React' },
      ],
    });
    const addRawItem = () => {
      const raw = toRaw(state.items); // 获取原始数组
      raw.push({ id: raw.length + 1, name: 'Angular' });
      console.log('raw', raw);
    };

    return () => (
      <div>
        <h1>技术栈</h1>
        <ul>
          {state.items.map((item) => (<li key={item.id}>{item.name}</li>))}
        </ul>
        <button onClick={addRawItem}>添加项</button>
      </div>
    );
  },
});

展示为:

使用建议:

1、优先使用 Vue 的响应式系统,toRaw 只在特殊场景中使用。

2、📢:注意原始对象的修改不会触发视图更新。

3、避免过度依赖 toRaw,以免破坏响应式的优势。


http://www.kler.cn/a/402822.html

相关文章:

  • 网络爬虫总结与未来方向
  • 【Python系列】字典灵活的数据存储与操作
  • React中 setState 是同步的还是异步的?调和阶段 setState 干了什么?
  • git使用(二)
  • C语言教程指针笔记整理(二)
  • ChatGPT 与其他 AI 技术在短视频营销中的技术应用与协同策略
  • 前端:JavaScript (学习笔记)【1】
  • 学习与理解LabVIEW中的格式化写入(Format into String)函数
  • ioDraw Mac客户端安装教程
  • 目录背景缺少vscode右键打开选项
  • 基于xr-frame实现微信小程序的手部、手势识别3D模型叠加和石头剪刀布游戏功能
  • 【蓝桥杯备赛】123(前缀和的复杂应用)
  • 【企业级分布式系统】 Kafka集群
  • 局域网协同办公软件,2024安全的协同办公软件推荐
  • OAI-5G开源通信平台实践(四)
  • 手机怎么玩腐蚀?GameViewer远程串流玩腐蚀教程
  • Facebook投放nutra广告最新指南
  • A股分钟tick以及level2行情数据获取方法已经策略分享
  • Linux下多线程
  • Python+7z:将文件和目录压缩为ZIP文件
  • 蓝队技能-应急响应篇日志自动采集日志自动查看日志自动化分析Web安全内网攻防工具项目
  • C#开发最快的浏览器,打造极速浏览体验
  • Paint 学习笔记
  • 51单片机基础05 实时时钟-思路及代码参考2、3
  • 掌握Git分布式版本控制工具:从基础到实践
  • 2025蓝桥杯(单片机)备赛--扩展外设之超声波测距原理与应用(十一)