我有一个像这样初始化的组件
<custom :opts="{map: false}"></custom>
并且有与此类似的HTML
<template id="custom">
<div v-if="opts.map">
I'm awesome
</div>
<button v-on:click="show"></button>
</template>
其中
function show(){
this.opts = {map:true} // (1) <-- This is working and I could see hidden div
this.opts.map = true // (2) <-- For some reason not working
Vue.set(this.opts, 'map', true) // (3) <-- Still not working
}
所以我的问题是为什么变体2 不起作用,我应该进行哪些更改以使控件对单击按钮时的值重置做出反应。或正确解释为什么(1)有效,但(2)不起作用-也将被视为答案。
答案 0 :(得分:1)
代码(所有3个版本)的真正问题是从组件内部更改组件的属性。在惯用的Vue中,只有父级才能更改属性。如果组件需要进行更改,则应向父对象发出一个事件,并让父对象进行必要的更改。否则,组件“拥有”该属性会有歧义。
所有道具在子级属性和父级属性之间形成单向绑定:当父级属性更新时,它将向下流到子级,但不会反过来。
答案 1 :(得分:0)
在这里可能会偏离基准,但我相信会发生这种情况,因为在vue中props
组件没有反应性,因此无法深入观察其对象。或者更确切地说,它们是“有点反应性”的,重新分配根属性确实会导致DOM更新,但是预计不会手动完成,并且在开发版本上执行此操作时您会看到警告:
[Vue警告]:避免直接更改道具,因为每当父组件重新渲染时,该值就会被覆盖。而是使用基于属性值的数据或计算属性。道具被突变:“ ...”
以及为什么道具首先不能完全反应的原因:https://vuejs.org/v2/guide/components-props.html#One-Way-Data-Flow
要解决整个问题,您必须将任何必要的道具传递给组件data
,如果这些道具作为嵌套对象传递,则您可能还希望完全避免从组件内部进行变异,因为它将传播到组件除非明确指出,否则可能是坏消息的来源。