我是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)
编辑1:@Craig的答案帮助我根据属性名称和每个属性上的set调用传播更改.但是,如果数据很复杂并且问候语基于节点的许多属性,那该怎么办呢?在这个示例中,我经历了一个简单的用例,但在现实世界中,窗口小部件基于从服务器动态发送的许多属性,并且每个窗口小部件属性根据窗口小部件的类型而不同.例如"欢迎,{{message.name}}.温度{{message.location}}是{{message.temp}}."等等.由于节点的属性不同,有没有什么方法可以更新完整的树而不遍历我们的javascript代码中的整个树,并调用每个属性上的set.在VUE框架中有什么可以处理这个吗?
Vue
除非您使用set方法(请参阅:https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats),否则无法检测属性添加或删除,因此您需要执行以下操作:
Vue.set(data, 'name', 'changed world')
这是JSFiddle:https://jsfiddle.net/f7ae2364/
编辑
在你的情况下,如果你想避免遍历你的数据,我认为你将不得不放弃观看prop
,而是去竞赛总线.因此,首先要为您的组件设置一个全局总线来监听:
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/