⼦组件可以直接改变⽗组件的数据吗?
VueJs 272
这是⼀个实践知识点,组件化开发过程中有个单项数据流原则,不在⼦组件中修改⽗组件是个常识问题。
参考⽂档:https://staging.vuejs.org/guide/components/props.html#one-way-data-flow
思路
- 讲讲单项数据流原则,表明为何不能这么做
- 举⼏个常⻅场景的例⼦说说解决⽅案
- 结合实践讲讲如果需要修改⽗组件状态应该如何做
回答范例
1、所有的 prop 都使得其⽗⼦之间形成了⼀个单向下⾏绑定:⽗级 prop 的更新会向下流动到⼦组件中,但是反过来则不⾏。这样会防⽌从⼦组件意外变更⽗级组件的状态,从⽽导致你的应⽤的数据流向难以理解。另外,每次⽗级组件发⽣变更时,⼦组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在⼀个⼦组件内部改变 prop。如果你这样做了,Vue 会在浏览器控制台中发出警告。
const props = defineProps(['foo'])
//
下⾯⾏为会被警告, props是只读的!
props.foo = 'bar'
2、实际开发过程中有两个场景会想要修改⼀个属性:
这个 prop ⽤来传递⼀个初始值;这个⼦组件接下来希望将其作为⼀个本地的 prop 数据来使⽤。在这
种情况下,最好定义⼀个本地的 data,并将这个 prop ⽤作其初始值:
const props = defineProps(['initialCounter'])
const counter = ref(props.initialCounter)
这个 prop 以⼀种原始的值传⼊且需要进⾏转换。在这种情况下,最好使⽤这个 prop 的值来定义⼀个计
算属性:
const props = defineProps(['size'])
// prop变化,计算属性⾃动更新
const normalizedSize = computed(() => props.size.trim().toLowerCase())
3、实践中如果确实想要改变⽗组件属性应该emit⼀个事件让⽗组件去做这个变更。注意虽然我们不能直接修改⼀个传⼊的对象或者数组类型的prop,但是我们还是能够直接改内嵌的对象或属性。