[Vuejs]-Input field unable to change model when component and model are dynamically created

0👍

As the OP’s comments, the root cause should be how to sync textarea value between child and parent component.

The issue the OP met should be caused by parent component always pass same value to the textarea inside the child component, that causes even type in something in the textarea, it still bind the same value which passed from parent component)

As Vue Guide said:

v-model is essentially syntax sugar for updating data on user input
events, plus special care for some edge cases.

The syntax sugar will be like:

the directive=v-model will bind value, then listen input event to make change like v-bind:value="val" v-on:input="val = $event.target.value"

So adjust your codes to like below demo:

  1. for input, textarea HTMLElement, uses v-bind instead of v-model

  2. then uses $emit to popup input event to parent component

  3. In parent component, uses v-model to sync the latest value.

Vue.config.productionTip = false
Vue.component('child', {
  template: `<div class="child">
        <label>{{value.name}}</label><button @click="changeLabel()">Label +1</button>
        <textarea :value="value.body" @input="changeInput($event)"></textarea>
    </div>`,
  props: ['value'],
  methods: {
    changeInput: function (ev) {
      let newData = Object.assign({}, this.value)
      newData.body = ev.target.value
      this.$emit('input', newData) //emit whole prop=value object, you can only emit value.body or else based on your design.
      // you can comment out `newData.body = ev.target.value`, then you will see the result will be same as the issue you met.
    },
    changeLabel: function () {
      let newData = Object.assign({}, this.value)
      newData.name += ' 1'
      this.$emit('input', newData)
    }
  }
});

var vm = new Vue({
  el: '#app',
  data: () => ({
    options: [
      {id: 0, name: 'Apple', body: 'Puss in Boots'},
      {id: 1, name: 'Banana', body: ''}
    ]
  }),
})
.child {
  border: 1px solid green;
}
<script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
<div id="app">
  <span> Current: {{options}}</span>
  <hr>
  <div v-for="(item, index) in options" :key="index">
    <child v-model="options[index]"></child>
  </div>
</div>

Leave a comment