[Vuejs]-All dynamically generated components are changing to the same value in VUEJS

1👍

Even though you are creating new components by pushing them into the children array, they are still getting bound to the same data via the line v-bind="{myMessage: m3}". Whenever you change m3, it will be passed down to all the child components and they will all render the same message.

This is an odd way of creating custom components since you could easily do so using the templating syntax or render function provided by Vue.

Solution 1 – Recommended

Change your approach – push message strings instead of card component definitions into children and use MyCmp inside v-for to render the message cards.

So the new template could be refactored as :-

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

And inside App component, you can replace this.children.push(MyCmp) with this.children.push(messageVariable); where messageVariable contains the message that you receive from the input box.

Why is the recommended? This is a standard approach where component lists are rendered based on an array of data. It will be easier to scale and maintain.

Solution 2

You can use the v-once directive to bind the message one-time as static text. The binding won’t be updated even if m3 changes on the parent.

Then MyCmp template will become :-

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

0👍

You bind myMessage of all your components instances with one variable m3. So, when m3 is changed myMessage in all instances changes respectively. Use another variable (e.g. msg) for rendering the message and then use myMessage property only for the initialisation of msg, like this:

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>
   `
};
👤Lana

Leave a comment