javascript - VueJS 不会从组件重新渲染列表

标签 javascript vue.js vuex

尝试通过“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/

相关文章:

javascript - 将文本从一个 INPUT 拖动到另一个 INPUT,而不从源 INPUT 中删除文本

javascript - 我想我没有正确使用 Backbone JS 的 View ?

javascript - 如何允许不同的更新 - Meteor collection.allow

ecmascript-6 - 如何从 Vuex/Vuejs 中的 Action 调用另一个 Action ?

javascript - 来自 v-item-group 的错误 : Multiple root nodes returned from render function.

javascript - 鼠标悬停在 map 区域上显示图像,鼠标悬停则隐藏

vue.js - V-工具提示 : Close Popover from a method

vue.js - 如何将动态参数添加到 graphql 查询中

javascript - Vue 内联模板不渲染

vue.js - Nuxt.js:从 vuex 开始加载指示器