【问题标题】:Why is toRaw(obj) maintaining reactivity?为什么 toRaw(obj) 保持反应性?
【发布时间】:2021-05-10 06:35:43
【问题描述】:

我对 toRaw() 的反应性感到困惑。

App.vue

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <TheForm @newThing="addNewThing" />
  <TheList :allTheThings="allTheThings" />
</template>

<script setup>
  import TheForm from "./components/TheForm.vue";
  import TheList from "./components/TheList.vue";

  import { ref } from "vue";

  const allTheThings = ref([]);
  const addNewThing = (thing) => allTheThings.value.push(thing);
</script>

TheForm.vue

<template>
  <h3>Add New Thing</h3>
  <form @submit.prevent="addNewThing">
    <input type="text" placeholder="description" v-model="thing.desc" />
    <input type="number" placeholder="number" v-model="thing.number" />
    <button type="submit">Add New Thing</button>
  </form>
</template>

<script setup>
  import { reactive, defineEmit, toRaw } from "vue";

  const emit = defineEmit(["newThing"]);

  const thing = reactive({
    desc: "",
    number: 0,
  });

  const addNewThing = () => emit("newThing", thing);
</script>

TheList.vue

<template>
  <h3>The List</h3>
  <ol>
    <li v-for="(thing, idx) in allTheThings" :key="idx">
      {{ thing.desc }} || {{ thing.number }}
    </li>
  </ol>
</template>

<script setup>
  import { defineProps } from "vue";

  defineProps({
    allTheThings: Array,
  });
</script>

由于代码将代理传递给数据,因此它的行为很可疑:提交表单后,如果您重新编辑表单字段中的数据,它也会编辑列表的输出。很好。

所以我想在addNewThing 中传递thing 的非反应性副本:

  const addNewThing = () => {
    const clone = { ...thing };
    emit("newThing", clone);
  };

它按预期工作。

如果我改用const clone = toRaw(thing); 是行不通的。 如果我记录每个的输出,{ …thing}toRaw(thing) 完全相同,那么为什么toRaw() 似乎没有失去它的反应性?

任何光照都会,嗯……很有启发性。

【问题讨论】:

    标签: vuejs3 vue-reactivity vite


    【解决方案1】:

    我认为问题在于对 toRaw 的作用存在误解。

    返回 reactivereadonly 代理的原始原始对象。 这是一个逃生舱口,可用于临时读取而不会产生代理访问/跟踪开销或写入而不触发更改。不建议持有对原始对象的持久引用。谨慎使用。

    toRaw 将返回原始代理,而不是代理内容的副本,因此您使用const clone = { ...thing }; 的解决方案是恕我直言,希望这个解释就足够了。

    查看类似问题了解更多详情?vue3 reactive unexpected behaviour

    【讨论】:

    • 谢谢丹尼尔。细节中是魔鬼等等。
    猜你喜欢
    • 1970-01-01
    • 2018-06-11
    • 1970-01-01
    • 2021-02-27
    • 2019-02-13
    • 2012-10-11
    • 1970-01-01
    • 1970-01-01
    • 2020-01-08
    相关资源
    最近更新 更多