【发布时间】:2023-02-02 18:41:46
【问题描述】:
和这位家长...
<template>
<h2>Parent</h2>
{{ parent.a }}
{{ parent.b }}
<ChildComponent :data="parent" />
</template>
<script setup>
import { reactive } from 'vue'
import ChildComponent from './components/ChildComponent.vue'
const parent = reactive({ a: 1, b: 2 })
</script>
而这个孩子...
<template>
<h2>Child component</h2>
<p>{{ child.a }}</p>
<p>{{ child.b }}</p>
<input type="text" v-model="child.b" />
</template>
<script setup>
import { reactive } from 'vue'
const props = defineProps(['data'])
const child = reactive(props.data)
child.a = 'why do i update the parent?'
</script>
为什么要在这里更新父母的数据?我认为随着“数据”道具的绑定是单向的,我需要一个发射器将数据发送回父级吗?相反,对子组件中 child 对象的任何更改都会更新父组件中的 parent 对象。
在文档中说
当对象和数组作为 props 传递时,虽然子组件不能改变 prop 绑定,但它将能够改变对象或数组的嵌套属性。这是因为在 JavaScript 中,对象和数组是通过引用传递的,而 Vue 防止这种突变的代价高得不合理。
但是从我的示例来看,
a和b没有嵌套?
【问题讨论】:
-
我可以想到这个语句——reactive 返回对象的一个 reactive 副本。反应式转换是“深度”的。建议专门使用反应式代理,避免依赖原始对象。其次,虽然从反应式返回的对象是深度反应式的(为对象设置任何值都会触发 Vue 中的反应)
-
所以,我的假设是,使用反应式 api 可能是原因。您可以尝试解构反应对象,例如
const parent = {...reactive({ a: 1, b: 2 })}并检查这是否是罪魁祸首。 -
感谢您的评论,尽管解构
reactive将完全失去反应性。你是对的,尽管reactive的使用是问题所在 - 因为它正在创建原始的反应副本..我会添加一个答案。