【问题标题】:Vue js - Update index value doesn't update the second component's viewVue js - 更新索引值不会更新第二个组件的视图
【发布时间】:2017-06-07 14:04:05
【问题描述】:

我有一个非常简单的 Vue js 页面,如下所示:

<html>
    <head>
        <script src="https://unpkg.com/vue/dist/vue.js"></script>
    </head>
    <body>
        <div id="main-container">
            <div id="contact-table">
                <table>
                    <thead>
                        <tr>
                            <th>Contact Name</th>
                            <th>Email</th>
                        </tr>
                    </thead>
                    <tbody v-for="contact in contacts">
                        <tr v-on:click="selectContact(contact.index)">
                            <td>
                                {{contact.name}}
                            </td>
                            <td>
                                {{contact.email}}
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
            <div id="contact-form">
                <input type="text" v-model="contactName"/>
                <input type="text" v-model="contactEmail"/>
                <button type="button" v-on:click="updateContact">Update Contact</button>
            </div>
        </div>
    </body>
    <script>
        var hub = {
            contacts: [
                {
                    name: "James",
                    email: "Jame@bond.com",
                    index: 0
                },
                {
                    name: "Mary",
                    email: "Mary@lamb.com",
                    index: 1
                }
            ],
            index: 0
        };

        var contactTable = new Vue({
            el: "#contact-table",
            data: {
                contacts: hub.contacts
            },
            methods: {
                selectContact: function(index) {
                    hub.index = index;
                    console.log(hub.index);
                }
            }
        });

        var contactForm = new Vue({
            el: "#contact-form",
            data: {
                contactName: hub.contacts[hub.index].name,
                contactEmail: hub.contacts[hub.index].email
            },
            methods: {
                updateContact: function() {
                    hub.contacts[hub.index].name = this.contactName;
                    hub.contacts[hub.index].email = this.contactEmail;
                }
            }
        });
    </script>
</html>

基本上它包含两个 Vue 部分——表格和输入表单。通过单击表中的行,它应该更改输入表单中的值,但单击更新联系人按钮,它应该更新表单详细信息。

第二部分运行良好 - 但是,当我单击表格的行时,虽然 console.log 告诉我 hub.index 已更新好,但输入表单中的视图却没有。

我相信这应该是双向绑定,所以我只是想知道我在哪里做错了。

【问题讨论】:

标签: javascript vue.js


【解决方案1】:

你的 hub 变量在 vue 实例之外,所以这个变量不是响应式的,这意味着如果这个变量改变 vue 不会更新 DOM。你也可以在 vue 的数据部分定义 hub 并使其成为响应式。

你还需要有一个事件总线,因为你要通信between your two components,你可以使用$emit发送一个事件,并使用$on监听其他组件中的组件。

这是您的代码的工作小提琴:https://jsfiddle.net/mimani/50ajs58L/1/

<script src="https://unpkg.com/vue/dist/vue.js"></script>

<body>
  <div id="main-container">
    <div id="contact-table">
      <table>
        <thead>
          <tr>
            <th>Contact Name</th>
            <th>Email</th>
          </tr>
        </thead>
        <tbody v-for="(contact, index) in contacts">
          <tr v-on:click="selectContact(index)">
            <td>
              {{contact.name}}
            </td>
            <td>
              {{contact.email}}
            </td>
          </tr>
        </tbody>
      </table>
    </div>
    <div id="contact-form">
      <input type="text" v-model="contactName" />
      <input type="text" v-model="contactEmail" />
      <button type="button" v-on:click="updateContact">Update Contact</button>
    </div>
  </div>
</body>
<script>
  var hub = {
    contacts: [{
      name: "James",
      email: "Jame@bond.com",
      index: 0
    }, {
      name: "Mary",
      email: "Mary@lamb.com",
      index: 1
    }],
    index: 0
  };
  var bus = new Vue()
  var contactTable = new Vue({
    el: "#contact-table",
    data: {
      contacts: hub.contacts
    },
    methods: {
      selectContact: function(index) {
        hub.index = index;
        console.log(hub.index);
        bus.$emit('updateIndex', index)
      }
    }
  });

  var contactForm = new Vue({
    el: "#contact-form",
    data: {
      contactName: hub.contacts[hub.index].name,
      contactEmail: hub.contacts[hub.index].email,
      index: hub.index
    },
    methods: {
      updateContact: function() {
        hub.contacts[this.index].name = this.contactName;
        hub.contacts[this.index].email = this.contactEmail;
      }
    },
    created() {
      var that = this
      bus.$on('updateIndex', function(index) {
        that.index = index
        that.contactName = hub.contacts[that.index].name
        that.contactEmail = hub.contacts[that.index].email
      })
    }
  });

</script>

这里我使用了事件总线,但是随着您的应用程序的增长,您可以考虑使用state management 技术,这将使您的变量可以访问所有组件,或者您可以使用在社区中流行的vuex。您可以查看thisthis的答案了解更多详情。

【讨论】:

  • 如果应用比较复杂,绝对推荐vuex。对于简单的情况,手动维护数据存储就足够了,就像您的回答一样。然而,在这样一个简单的例子中创建多个 Vue 实例看起来很奇怪。我建议 OP 在采取行动之前通读官方文档和示例 :)
  • @Leo 感谢您提供的信息。我还没有开始采取行动,此页面仅用于学习目的。 Vue js 非常酷,我正在尝试以 Vue js 的方式思考。
猜你喜欢
  • 2023-04-08
  • 2017-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-06
  • 2019-06-16
  • 2018-01-12
相关资源
最近更新 更多