Vue 3 中 toRaw 的用法详细讲解

 更新时间:2024年11月21日 11:27:58   作者:代码里的小猫咪  
`toRaw` 是 Vue3 提供的一个 API,用于获取响应式对象的原始非响应式对象,主要用于调试、与第三方库兼容以及避免无限递归更新等场景,使用时需要注意不要滥用,以免破坏响应式系统,感兴趣的朋友跟随小编一起看看吧

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,以免破坏响应式的优势。

到此这篇关于Vue 3 中 toRaw 的详细讲解的文章就介绍到这了,更多相关Vue 3 toRaw 的详细讲解内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 在vue中使用export default导出的class类方式

    在vue中使用export default导出的class类方式

    这篇文章主要介绍了在vue中使用export default导出的class类方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • Vue使用JsonView进行JSON数据展示

    Vue使用JsonView进行JSON数据展示

    Vue-JSON-Viewer 是一个用于在Vue项目中展示JSON数据的组件,它解决了在项目开发中面临的展示JSON数据的需求,下面就跟随小编一起来了解下它的具体使用吧
    2025-03-03
  • 解决vue-loader加载不上的问题

    解决vue-loader加载不上的问题

    这篇文章主要介绍了解决vue-loader加载不上的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-10-10
  • vue实现多组关键词对应高亮显示功能

    vue实现多组关键词对应高亮显示功能

    最近小编遇到这样的问题,多组关键词,这里实现了关键词的背景色与匹配值的字体颜色值相同,下面通过定义关键词匹配改变字体颜色,本文通过实例代码给大家介绍的非常详细,需要的朋友参考下吧
    2019-07-07
  • vue3实现多层级列表的项目实践

    vue3实现多层级列表的项目实践

    本文主要介绍了vue3实现多层级列表的项目实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • vue 的keep-alive缓存功能的实现

    vue 的keep-alive缓存功能的实现

    本篇文章主要介绍了vue 的keep-alive缓存功能的实现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-03-03
  • 编写v-for循环的技巧汇总

    编写v-for循环的技巧汇总

    这篇文章主要介绍了编写更好的v-for循环的6种技巧,帮助大家更好的理解和使用vue框架,感兴趣的朋友可以了解下
    2020-12-12
  • Vue动态添加属性到data的实现

    Vue动态添加属性到data的实现

    在vue中请求接口中,一个请求方法可能对应后台两个请求接口,所以请求参数就会有所不同。需要我们先设置共同的参数,然后根据条件动态添加参数属性
    2022-08-08
  • Elementui el-input输入框校验及表单校验实例代码

    Elementui el-input输入框校验及表单校验实例代码

    输入框是使用非常多的元素,用来输入用户名、密码等等信息,Element提供了功能和样式丰富的输入框,下面这篇文章主要给大家介绍了关于Elementui el-input输入框校验及表单校验的相关资料,需要的朋友可以参考下
    2023-06-06
  • vuex提交state&&实时监听state数据的改变方法

    vuex提交state&&实时监听state数据的改变方法

    今天小编就为大家分享一篇vuex提交state&&实时监听state数据的改变方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-09-09

最新评论