如何启用对组件道具的深层更改的跟踪

时间:2018-06-26 14:29:04

标签: javascript vuejs2 vue-reactivity

我有一个像这样初始化的组件

<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)不起作用-也将被视为答案。

2 个答案:

答案 0 :(得分:1)

代码(所有3个版本)的真正问题是从组件内部更改组件的属性。在惯用的Vue中,只有父级才能更改属性。如果组件需要进行更改,则应向父对象发出一个事件,并让父对象进行必要的更改。否则,组件“拥有”该属性会有歧义。

One Way Data Flow

  

所有道具在子级属性和父级属性之间形成单向绑定:当父级属性更新时,它将向下流到子级,但不会反过来。

Sending Messages to Parents with Events

答案 1 :(得分:0)

在这里可能会偏离基准,但我相信会发生这种情况,因为在vue中props组件没有反应性,因此无法深入观察其对象。或者更确切地说,它们是“有点反应性”的,重新分配根属性确实会导致DOM更新,但是预计不会手动完成,并且在开发版本上执行此操作时您会看到警告:

  

[Vue警告]:避免直接更改道具,因为每当父组件重新渲染时,该值就会被覆盖。而是使用基于属性值的数据或计算属性。道具被突变:“ ...”

以及为什么道具首先不能完全反应的原因:https://vuejs.org/v2/guide/components-props.html#One-Way-Data-Flow

要解决整个问题,您必须将任何必要的道具传递给组件data,如果这些道具作为嵌套对象传递,则您可能还希望完全避免从组件内部进行变异,因为它将传播到组件除非明确指出,否则可能是坏消息的来源。