【问题标题】:Javascript (Vue.js) - Adding Table Rows to the Wrong Node in the DOMJavascript (Vue.js) - 将表格行添加到 DOM 中的错误节点
【发布时间】:2020-07-03 22:02:22
【问题描述】:

我正在尝试为第 5 版龙与地下城创建一个主动跟踪器。使用 Vue 中包含的 fetch 函数,我已经能够从游戏中获取所有免费可用的怪物的列表,并将它们渲染成一个无序列表。我已经为列表中的每个项目添加了一个onclick 事件,以便在单击名称时,将怪物对象的新实例附加到initiativeOrder 变量后自动添加到倡议表中,但我注意到一些异常行为。

首先,单击列表中的名称会导致新的表格行出现在 DOM 的表格之外。其次,如果您多次单击同一个名称,它不会在表格中添加具有相同信息的另一行,这是我所期望的。

如何更改标记和脚本,以便每次单击列表中的项目时,新项目总是出现在表中的适当位置?

<!doctype html>
<html class="no-js" lang="en-GB">
    <head>
        <meta charset="utf-8">
        <title>Final Year Project | Battle Tracker for 5th Edition Dungeons and Dragons</title>
        <meta name="description" content="A Battle Tracker for 5th edition Dungeons and Dragons written using Progressive Web Technologies.">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <link rel="manifest" href="site.webmanifest">
        <link rel="apple-touch-icon" href="icon.png">
        <!-- Place favicon.ico in the root directory -->

        <link rel="stylesheet" href="css/main.css">
        <link rel="stylesheet" href="css/normalize.css">
        <link rel="stylesheet" href="css/boilerplate.css">

        <meta name="theme-color" content="#160a0b">
    </head>

    <body>
        <!--[if IE]>
        <p class="browserupgrade">You are using an <strong>outdated</strong> browser. Please <a href="https://browsehappy.com/">upgrade your browser</a> to improve your experience and security.</p>
        <![endif]-->

        <main id="app">
            <div class="sidebar">
                <nav id="commands">
                    <ul>
                        <li>
                            <button type="button">Begin Encounter</button>
                        </li>
                    </ul>
                </nav>
            </div>
            <div id="library">
                <ul>
                    <creature-listing
                    v-for="(index, creature) in creatures"
                    v-bind:creature="creature"
                    v-on:click="addCreature(index)"></creature-listing>
                </ul>
            </div>
            <div id="initiative">
                <table>
                    <thead>
                        <tr>
                            <th>Initiative</th>
                            <th>Name</th>
                            <th>Hit Points</th>
                            <th>Armor Class</th>
                        </tr>
                    </thead>
                    <tbody>
                        <combatant
                        v-for="combatant in initiativeOrder"
                        v-bind:combatant="combatant">
                    </tbody>
                </table>
            </div>
        </main>

        <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.18/vue.min.js"></script>
        <!-- <script src="serviceworker.js"></script> -->
        <script src="js/app.js"></script>
    </body>
</html>
Vue.component(
    'creature-listing',
    {
        props: [
            'creature'
        ],
        template: '<li>{{ index }} {{ creature.name }}</li>'
    }
);

Vue.component(
    'combatant',
    {
        props: [
            'combatant'
        ],
        template: `
            <tr>
                <td>?</td>
                <td>{{ combatant.name }}</td>
                <td>{{ combatant.hit_points }}</td>
                <td>{{ combatant.armor_class }}</td>
            </tr>
        `
    }
)

var app = new Vue({
    el: '#app',
    data: {
        creatures: [],
        initiativeOrder: []
    },
    methods: {
        addCreature: function (index) {
            this.initiativeOrder.push(this.creatures[index]);
        }
    },
    created: function () {
        // this runs when the component is mounted
        fetch("creatures.json")
            .then(data => data.json())
            .then(creatures => { this.creatures = creatures })
    }
});

【问题讨论】:

  • 你应该有一个:key给你v-for,也许添加v-for=(combatant, i)... :key="i"
  • 我已将 HTML 中的 &lt;combatant&gt; 组件实例更改为如下所示:html &lt;combatant v-for="(combatant, i) in initiativeOrder" :key="i" v-bind:combatant="combatant"&gt; 但这让情况变得更糟。这些行仍然显示在错误的位置,并且没有显示任何信息。

标签: javascript html vue.js


【解决方案1】:

您的问题是自定义 tr 组件。表只需要tbody,thead,tr,td,th 元素,所以其他元素而不是预期的元素不属于表。您必须将整个表格放在您的组件中。

此问题与任何虚拟节点框架(如 Angular)有关,而不仅仅是 vue。

例子:

new Vue({
  data: {
    rows:["row1", "row2"]
  },
  components: {
    myrows: {
      props: ['row'],
      template:'<tr><td>{{row}}</td></tr>',
    },
    mytable: {
      props: ['rows'],
      template:'<table><tr><td>TEST</td></tr><tr v-for="row in rows"><td>{{row}}</td></tr></table>',
    }
  }
}).$mount('div')
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div>
  <table style='border:2px solid blue'><tr><td>TEST</td></tr><myrows v-for='row in rows' :row='row'></myrows></table>
  <mytable style='border:2px solid red' :rows='rows'></mytable>
</div>

您必须在组件中提供整个表格。您的代码必须如下所示:

new Vue({
  data: {
    creatures: [
      {name:"Bat", hit_points: 200, armor_class: 5},
      {name:"Org", hit_points: 250, armor_class: 25}
    ]
  },
  components: {
    creatures: {
      props: ['data'],
      template: `<table> 
                    <thead>
                        <tr>
                            <th>Initiative</th>
                            <th>Name</th>
                            <th>Hit Points</th>
                            <th>Armor Class</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr v-for='combatant in data'>
                            <td>?</td>
                            <td>{{ combatant.name }}</td>
                            <td>{{ combatant.hit_points }}</td>
                            <td>{{ combatant.armor_class }}</td>
                        </tr>
                    </tbody>
                </table>`
    }
  }
}).$mount('div')
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="initiative">
  <creatures :data="creatures"></creatures>
</div>

【讨论】:

  • "表格只需要 tbody,thead,tr,td,th 元素,所以其他元素而不是预期的元素不属于表格"。你的意思是说我不能在index.html文件中添加一个常规的表格,然后使用自定义标签来填充行吗?
  • 另外,我尝试将此解决方案插入到我自己的代码中,但它没有按预期工作。它试图展示什么?
  • Tables 工作如你所见,&lt;table&gt;&lt;tbody&gt;&lt;myrow&gt;... 不起作用
  • 用您的数据更新答案
  • 感谢您的澄清。这应该对我构建应用程序有很大帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-19
  • 2021-01-10
  • 2018-07-13
  • 1970-01-01
  • 2013-06-04
  • 2019-07-14
相关资源
最近更新 更多