为什么 toRaw(obj) 保持反应性?
Why is toRaw(obj) maintaining reactivity?
我对 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()
似乎没有失去它的反应性?
任何光照都会,好吧……启发。
我认为问题在于对 toRaw
的作用存在误解。
Returns the raw, original object of a reactive
or readonly
proxy. This is an escape hatch that can be used to temporarily read without incurring proxy access/tracking overhead or write without triggering changes. It is not recommended to hold a persistent reference to the original object. Use with caution.
toRaw
将 return 原始代理,而不是代理内容的副本,因此您使用 const clone = { ...thing };
的解决方案是恕我直言,希望这个解释足够了.
有关详细信息,请参阅类似问题
我对 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()
似乎没有失去它的反应性?
任何光照都会,好吧……启发。
我认为问题在于对 toRaw
的作用存在误解。
Returns the raw, original object of a
reactive
orreadonly
proxy. This is an escape hatch that can be used to temporarily read without incurring proxy access/tracking overhead or write without triggering changes. It is not recommended to hold a persistent reference to the original object. Use with caution.
toRaw
将 return 原始代理,而不是代理内容的副本,因此您使用 const clone = { ...thing };
的解决方案是恕我直言,希望这个解释足够了.
有关详细信息,请参阅类似问题