尝试通过“v-for”从 vuex 渲染一个数组。
“玩家卡”组件未呈现。 但是“td”解决方案工作正常。
我在 JSFiddle 上的例子
HTML:
<div id="app">
<button v-on:click="moveItem">
Move Item
</button>
<table cellspacing="2" border="1" cellpadding="5">
<tr>
<td v-for="(item, item_idx) in getItems" v-bind:key="item.col">{{ (item.card)? item.card.name : 'none' }}</td>
</tr>
<tr>
<player-card v-for="(item, item_idx) in getItems" v-bind:key="item.col" v-bind:item="item"></player-card>
</tr>
</table>
<br/>
<p>{{msg}}</p>
</div>
商店:
const store = new Vuex.Store({
state: {
items: [{ col: 0, row: 0 },
{ col: 1, row: 0 },
{ col: 2, row: 0, card: { name: "hello" } } ]
},
getters: {
getterItems: state => { return state.items; }
},
mutations: {
MOVE_ITEM: state => {
state.items[0].card = state.items[2].card;
delete state.items[2].card;
state.message = JSON.stringify(state.items);
}
}
});
组件:
Vue.component('player-card', {
props: {
item: {
type: Object,
required: true
}
},
template: '<td>{{ (item.card)? item.card.name : "none" }}</td>'
});
应用:
new Vue({
el: '#app',
store,
data: function() {
return {
msg: ''
}
},
computed: {
getItems() { return this.$store.getters.getterItems; }
},
mounted: function() {
this.msg = JSON.stringify(this.getItems);
},
methods: {
moveItem() {
this.$store.commit('MOVE_ITEM');
this.msg = JSON.stringify(this.getItems);
}
}
});
我已经尝试了很多解决方案,但还没有找到一个简单的解决方案。也许有人会提供不同的架构解决方案。
最佳答案
你只需要改变这一行:
<player-card v-for="(item, item_idx) in getItems" v-bind:key="item.col" v-bind:item="item"></player-card>
为此:
<td is="player-card" v-for="(item, item_idx) in getItems" v-bind:key="item.col" v-bind:item="item"></td>
这是必需的,因为您的模板是在 DOM 中指定的。浏览器将在 Vue 接近它之前解析模板标记。 HTML 解析规则只允许某些元素成为 <tr>
的直接子元素.任何其他元素将从 <table>
中拉出.当 Vue 开始解析模板时 <player-card>
元素将已经移出 <table>
.
如果您使用其他技术之一来指定模板,这将不是问题。
解决方法是使用 is
属性来指定组件而不是标签名称。
这在此处的文档中有解释:
https://v2.vuejs.org/v2/guide/components.html#DOM-Template-Parsing-Caveats
关于javascript - VueJS 不会从组件重新渲染列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57275968/