Vue.js $set 不更新显示
Vue.js $set not updating the display
我在使用 vuejs 1.0 $set(), i have made a jsfiddle 时遇到问题。 addQty1
工作并更新显示,而 addQty2
仅更新数据。
知道为什么会这样吗?
var TicketLine = Vue.extend({
template: '#ticketLineTemplate',
props: ['index', 'lines'],
data: function() {
var line = this.lines[this.index];
return {
qty: line.qty,
label: line.label
};
},
methods: {
addQty1: function() {
var line = this.lines[this.index];
line.qty++;
this.lines.$set(this.index, $.extend({}, line));
},
addQty2: function() {
var line = this.lines[this.index];
line.qty++;
this.lines.$set(this.index, line);
}
}
});
var lines = [{
qty: 1,
label: 'Pizza'
}, {
qty: 2,
label: 'Café'
}, {
qty: 1,
label: 'Soda'
}];
new Vue({
el: "#app",
data: {
lines: lines
},
components: {
'ticket-line': TicketLine
}
});
<div id="app">
<div id="ticket">
<table class="table">
<thead>
<th>Qty</th>
<th>Label</th>
<th>Actions</th>
</thead>
<tbody>
<template v-for="line in lines">
<ticket-line :index="$index" :lines="lines"></ticket-line>
</template>
</tbody>
</table>
</div>
<script type="text/x-template" id="ticketLineTemplate">
<tr>
<td>{{ qty }}</td>
<td>{{ label }}</td>
<td>
<button type="button" v-on:click="addQty1()">addQty1</button>
<button type="button" v-on:click="addQty2()">addQty2</button>
</td>
</tr>
</script>
</div>
真的没有理由将所有的行作为道具传递给每一行,只传递当前行。子组件不需要知道所有的行:
<ticket-line :index="$index" :line="line"></ticket-line>
var TicketLine = Vue.extend({
template: '#ticketLineTemplate',
props : ['index', 'line'],
data: function() {
return {
qty: this.line.qty,
label: this.line.label
};
},
methods: {
addQty1: function() {
this.qty++;
}
}
});
https://jsfiddle.net/6zovax1v/1/
至于您遇到此问题的原因,请阅读 "Change Detection Caveats" 以获取信息 http://vuejs.org/guide/reactivity.html。
编辑:对象没有深入观察。所以当你更新对象 qty
属性,然后 $set
对象时,Vue 说 "OK, this is the same object it was before, no need to update anything"。当您创建一个新对象时,Vue 会看到一个新对象并知道它需要更新。
我相信您可以直接在应该触发更新的项目的 属性 上使用 $set
:
addQty1: function() {
var qty = this.lines[this.index].qty;
qty++;
this.lines[this.index].$set('qty',qty);
);
},
编辑 2:经过测试,该代码对我不起作用。我认为这里对你来说最好的解决方案是重构你的结构,让每一行都是一个只知道自己的组件。我知道您说过您的应用程序中存在这种情况的原因,但应该有另一种更合适的解决方案。组件不需要知道整个数组,这就是组件的想法。如果他们需要互动,您可以使用 .sync
或事件广播。无论如何,很抱歉我无法让代码正常工作,希望你能解决这个问题。
我在使用 vuejs 1.0 $set(), i have made a jsfiddle 时遇到问题。 addQty1
工作并更新显示,而 addQty2
仅更新数据。
知道为什么会这样吗?
var TicketLine = Vue.extend({
template: '#ticketLineTemplate',
props: ['index', 'lines'],
data: function() {
var line = this.lines[this.index];
return {
qty: line.qty,
label: line.label
};
},
methods: {
addQty1: function() {
var line = this.lines[this.index];
line.qty++;
this.lines.$set(this.index, $.extend({}, line));
},
addQty2: function() {
var line = this.lines[this.index];
line.qty++;
this.lines.$set(this.index, line);
}
}
});
var lines = [{
qty: 1,
label: 'Pizza'
}, {
qty: 2,
label: 'Café'
}, {
qty: 1,
label: 'Soda'
}];
new Vue({
el: "#app",
data: {
lines: lines
},
components: {
'ticket-line': TicketLine
}
});
<div id="app">
<div id="ticket">
<table class="table">
<thead>
<th>Qty</th>
<th>Label</th>
<th>Actions</th>
</thead>
<tbody>
<template v-for="line in lines">
<ticket-line :index="$index" :lines="lines"></ticket-line>
</template>
</tbody>
</table>
</div>
<script type="text/x-template" id="ticketLineTemplate">
<tr>
<td>{{ qty }}</td>
<td>{{ label }}</td>
<td>
<button type="button" v-on:click="addQty1()">addQty1</button>
<button type="button" v-on:click="addQty2()">addQty2</button>
</td>
</tr>
</script>
</div>
真的没有理由将所有的行作为道具传递给每一行,只传递当前行。子组件不需要知道所有的行:
<ticket-line :index="$index" :line="line"></ticket-line>
var TicketLine = Vue.extend({
template: '#ticketLineTemplate',
props : ['index', 'line'],
data: function() {
return {
qty: this.line.qty,
label: this.line.label
};
},
methods: {
addQty1: function() {
this.qty++;
}
}
});
https://jsfiddle.net/6zovax1v/1/
至于您遇到此问题的原因,请阅读 "Change Detection Caveats" 以获取信息 http://vuejs.org/guide/reactivity.html。
编辑:对象没有深入观察。所以当你更新对象 qty
属性,然后 $set
对象时,Vue 说 "OK, this is the same object it was before, no need to update anything"。当您创建一个新对象时,Vue 会看到一个新对象并知道它需要更新。
我相信您可以直接在应该触发更新的项目的 属性 上使用 :$set
addQty1: function() {
var qty = this.lines[this.index].qty;
qty++;
this.lines[this.index].$set('qty',qty);
);
},
编辑 2:经过测试,该代码对我不起作用。我认为这里对你来说最好的解决方案是重构你的结构,让每一行都是一个只知道自己的组件。我知道您说过您的应用程序中存在这种情况的原因,但应该有另一种更合适的解决方案。组件不需要知道整个数组,这就是组件的想法。如果他们需要互动,您可以使用 .sync
或事件广播。无论如何,很抱歉我无法让代码正常工作,希望你能解决这个问题。