vue JS没有将更改从父级传播到组件

时间:2017-01-23 18:55:28

标签: javascript vue.js vuejs2 vue-component

我是Vue Framework的新手。我试图在添加或删除属性时将更改从父级传播到子级,或者在稍后阶段在组件外部更新。在下面的代码片段中,我尝试编写一个组件,该组件根据节点的name属性显示问候消息,该节点作为属性从父节点传递。

如果节点包含属性" name" (在下面的代码段中注释)初始化时。但是如果在后面的执行阶段添加了name属性(这里为了演示目的,我添加了一个设置超时并应用了)。该组件抛出错误,并且不会反映更改。我不知道如何传播组件中动态属性的更改,这些更改是基于组件外部的其他事件生成的。

基本上我想基于传递给它的属性以动态方式更新基于服务器响应显示不同类型小部件的组件。每当属性更新时,我希望组件自行更新。为什么双向绑定在Vuejs中无法正常工作?



Vue.component('greeting', {
    template: '#treeContainer',
    props: {'message':Object},
    watch:{
        'message': {
            handler: function(val) {
                console.log('###### changed');
            },
            deep: true
        }
    }
});

var data = {
    note: 'My Tree',
    // name:"Hello World",
    children: [
      { name: 'hello' },
      { name: 'wat' }
    ]
}

function delayedUpdate() {
    data.name='Changed World';
    console.log(JSON.stringify(data));
}

var vm = new Vue({
    el: '#app',
    data:{
        msg:data
    },
    method:{ }
});

setTimeout(function(){ delayedUpdate() ;}, 1000)

<script src="https://vuejs.org/js/vue.js"></script>
<div id="app">
  <greeting :message="msg"></greeting>
</div>
<script  type="text/x-template"  id="treeContainer">
	<h1>{{message.name}}</h1>
</script>
&#13;
&#13;
&#13;

编辑1:@ Craig的回答帮助我根据属性名称和每个属性调用set来传播更改。但是,如果数据很复杂并且问候语基于节点的许多属性,那该怎么办呢?在这个示例中,我经历了一个简单的用例,但在现实世界中,窗口小部件基于从服务器动态发送的许多属性,并且每个窗口小部件属性根据窗口小部件的类型而不同。喜欢&#34;欢迎,{{message.name}}。 {{message.location}}的温度为{{message.temp}}。 &#34;等等。由于节点的属性不同,有没有什么方法可以更新完整的树而不遍历我们的javascript代码中的整个树,并调用每个属性上的set。在VUE框架中有什么可以处理这个吗?

1 个答案:

答案 0 :(得分:5)

Vue无法检测属性添加或删除,除非您使用set方法(请参阅:https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats),因此您需要执行以下操作:

Vue.set(data, 'name', 'changed world')

这是JSFiddle:https://jsfiddle.net/f7ae2364/

修改

在您的情况下,如果您想避免遍历数据,我认为您将不得不放弃观看prop,而是选择event bus。因此,首先要为您的组件设置一个全局总线来监听:

var bus = new Vue({});

然后,当您收到新数据时,将$emit事件发送到总线上,并附上更新后的数据:

bus.$emit('data-updated', data);

在组件内部监听该事件(可以放在创建的钩子中),更新消息并强制vue重新渲染组件(我在这里使用ES6) :

created(){
   bus.$on('data-updated', (message) => {
     this.message = message;
     this.$forceUpdate();
   })
}

这是JSFiddle:https://jsfiddle.net/9trhcjp4/