在VUEJS中,所有动态生成的组件都将更改为相同的值

时间:2019-11-17 17:13:29

标签: vue.js vue-component

我们正在Vuejs中构建一个聊天应用程序,现在每个聊天消息都是应用程序中的组件,现在每当我们更改一个聊天消息的值时,所有聊天消息的值都会改变

正在发生的事情

enter image description here

源代码

应用组件

const App = new Vue({
      el: '#myApp',
      data: {
        children: [
          MyCmp
        ],
        m1: '',
        m2: '',
        m3: 'Hello world',
        m4: 'How are you'
      },
      methods: {
        sendMessage (event) {
          if(event.key == "Enter") {
            this.m2= this.m3;
            this.children.push(MyCmp);
          }
        },
      }
    });

组件代码

let MyCmp = {
      props: ['myMessage'],
      template: `
      <li class="self">
          <div class="avatar"><img src="" draggable="false"/></div>
          <div class="msg">
            <p>{{ myMessage }}</p>
          </div>
      </li>
      `
    };

**查看组件正在生成的位置**

<ol class="chat">
        <template v-for="(child, index) in children">
          <component :is="child" :key="child.name" v-bind="{myMessage: m3}"></component>
        </template>
    </ol>

2 个答案:

答案 0 :(得分:1)

即使通过将新组件推入子数组来创建新组件,它们仍将通过行v-bind="{myMessage: m3}"绑定到相同数据。每当您更改m3时,它将被向下传递到所有子组件,它们将呈现相同的消息。

这是一种创建自定义组件的奇怪方法,因为您可以使用Vue提供的模板语法或渲染功能轻松地做到这一点。

解决方案1-推荐

更改您的方法-将消息字符串而不是卡组件定义推送到children中,并在MyCmp内使用v-for来呈现消息卡。

因此,新模板可以重构为:-

<ol class="chat">
    <template v-for="(message, index) in children">
        <my-cmp :key="index" :my-message="message"></my-cmp>
    </template>
</ol>

在App组件内部,您可以将this.children.push(MyCmp)替换为this.children.push(messageVariable);,其中messageVariable包含从输入框中收到的消息。

为什么推荐?这是一种标准方法,其中基于数据数组呈现组件列表。将会更容易扩展和维护。

解决方案2

您可以使用v-once指令将消息一次性绑定为静态文本。即使m3在父级上更改,绑定也不会更新。

然后MyCmp模板将变为:-

<li class="self">
    <div class="avatar"><img src="" draggable="false"/></div>
        <div class="msg">
        <p v-once>{{ myMessage }}</p>
    </div>
</li>

答案 1 :(得分:0)

您将所有组件实例的myMessage与一个变量m3绑定。因此,当m3更改为myMessage时,所有实例都将分别更改。使用另一个变量(例如msg)来呈现消息,然后仅将myMessage属性用于msg的初始化,如下所示:

let MyCmp = {
  props: ['myMessage'],
  data: function () {
    return {
      msg: this.myMessage
    }
  },
  template: `
    <li class="self">
      <div class="avatar"><img src="" draggable="false"/></div>
        <div class="msg">
          <p>{{ msg }}</p>
        </div>
    </li>
   `
};