我有一个JavaScript对象,我试图绑定到Vue视图。
我正在运行一个使用AJAX更新JavaScript对象的函数,我期望Vue绑定到JS对象并在对象更新时更新视图,但不会发生。
研究建议在Vue声明中进行AJAX调用,但由于其他限制,我宁愿不这样做。
我已经创建了一个小提琴来说明问题是什么,因为它可以在没有AJAX部分的情况下重现,也可以粘贴下面的代码。
https://jsfiddle.net/g6u2tph7/5/
提前感谢您的时间和智慧。
谢谢,
vmitchell85
的JavaScript
window.changeTheData = function (){
externalJSSystems = [{description: 'Baz'}, {description: 'Car'}];
document.getElementById("log").innerHTML = 'function has ran...';
// This doesn't update the Vue data
}
var externalJSSystems = [{description: 'Foo'}, {description: 'Bar'}];
Vue.component('systable', {
template: '#sysTable-template',
data() {
return {
systems: externalJSSystems
};
}
});
new Vue({
el: 'body'
});
HTML
<systable :systems="systems"></systable>
<button type="button" onclick="changeTheData()">Change</button>
<br><br>
<div id="log"></div>
<template id="sysTable-template">
<table>
<thead>
<tr>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr v-for="sys in systems">
<td>{{ sys.description }}</td>
</tr>
</tbody>
</table>
</template>
答案 0 :(得分:3)
试试这个:
externalJSSystems.push({description: 'Baz'}, {description: 'Car'});
它会将新对象附加到 externalJSSystems ,视图将会更新。你的例子为什么不起作用?因为您要为 externalJSSystems 分配一个新的Array
引用,但Vue仍在观看旧版本。
要实现您的目标,请不要分配新的Array
实例,但要清除它。例如:
window.changeTheData = function (){
externalJSSystems.length = 0
externalJSSystems.push({description: 'Baz'}, {description: 'Car'});
}
答案 1 :(得分:2)
当实例化systable
组件的那个实例时,Vue会添加一个&#34; Observer&#34;类到初始externalJSSystems
数组 - 扩展Array的原型,为每个属性添加getter / setter,并维护Component data
之间的双向绑定原始数组。 changeTheData()
方法用一个全新的数组(缺少Observer)覆盖了Vue修改的externalJSSystems
数组,从而破坏了双向绑定。
通过这种方式,externalJSSystems.push( … )
可以正常工作,因为默认的数组方法(&#39; push&#39;,&#39; pop&#39;,&#39; shift&#39;,&#39;未移位&#39;,&#39; splice&#39;,&#39; sort&#39;和&#39;反向&#39;)已经变异,以便它们由Observer处理。
我认为你所寻找的行为的关键在于Vue组件&#34;道具&#34; - http://vuejs.org/guide/components.html#Props。事实上,您的组件标记 - <systable :systems="systems"></systable>
- 似乎已经设置为将动态数据传递给Component实例。现在,:systems="systems"
没有做任何事情。通过在Parent Vue范围中定义systems
,并在组件注册中将systems
定义为prop(s)
,您可以将动态数据传递到该父范围内的组件。
<强>组件强>
Vue.component('systable', {
template: '#sysTable-template',
props: {
systems: Array
}
});
Vue实例
var vm = new Vue({
el: 'body',
data: {
systems: externalJSSystems
}
});
你可以在这个小提琴中看到它:https://jsfiddle.net/itopizarro/ycr12dgw/
我缓存了Vue实例 - var vm = new Vue({ … })
- 因此changeTheData
方法可以访问其systems
数据。 这为您的外部changeTheData()
方法提供了对您定义system
的Vue实例的引用 - 从而为其提供了修改(无需替换或迭代添加/删除项目...)的数组数据。
答案 2 :(得分:0)
不是将系统设为数据属性,而是将其设为计算属性。像其他答案所说的那样,引用的是旧的对象。但是如果你使systems
成为计算属性,它将自动监视计算中使用的任何变量(如externalJSSystems
)并重新计算计算属性。
Vue.component('systable', {
template: '#sysTable-template',
computed: {
systems() {
return externalJSSystems;
}
}
});