Home > database >  Updating a a json in Vue
Updating a a json in Vue

Time:10-30

The text does not not update. Here is our code.

<some-builder :blaa="{name: 'something', type: 1}"></some-builder>

On the some-builder.vue

<input type="text" v-model="blaa.type" />
<button type="button"  @click="selectType('1')">1</button>
<button type="button"  @click="selectType('2')">2</button>
<button type="button"  @click="selectType('3')">3</button>


export default {
  props: ["blaa"],
  components: {},
  methods: {
    selectType(t) {
      this.blaa.type = t;
      console.log(this.blaa);
    },
  },
};

As you can see we have a click event that would change the type of blaa json. The console.log works just fine but the text box that has model blaa.type does not change.

Any help is much appreciated.

CodePudding user response:

Since vue (no matter is Vue2 or Vue3) is One-Way Data Flow, you can't change the parent data in children directly.


in Vue2

// parent component

<child-component
    :blaa="blaa"
    @update-blaa="updateBlaa"/>

export default {
    data() {
        return {
           blaa: {}
        }
    },
    methods: {
        updateBlaa(newValue) {
            this.blaa = newValue;
        }
    }
}

// child component

<input type="text" v-model="computedBlaa.type" />
<button type="button"  @click="selectType('1')">1</button>
<button type="button"  @click="selectType('2')">2</button>
<button type="button"  @click="selectType('3')">3</button>

export default {
    props: [
       'blaa'
    ],
    computed: {
        computedBlaa: {
            get() {
                return this.blaa;
            },
            set(value) {
                this.$emit('update-blaa', value);
            }
        }
    },
    methods: {
        selectType(t) {
           this.computedBlaa.type = t;
        }
    }
}

CodePudding user response:

mutating the prop inside the child component is not a good approach therefore, you can do a emit instead

Parent.vue

<some-builder :blaa="blaa" @update-blaa="updateBlaa"></some-builder>

export default {
 data() {
  return {
   blaa: {name: 'something', type: 1},
  };
 },
 methods: {
  updateBla(val) {
   this.blaa.type = val;
  },
 }
}

and then use :value instead of v-model in some-builder component as shown in below

<input type="text" :value="blaa.type" @input="$emit('update-blaa', $event.target.value)" />
<button type="button"  @click="selectType('1')">1</button>
<button type="button"  @click="selectType('2')">2</button>
<button type="button"  @click="selectType('3')">3</button>


export default {
  props: ["blaa"],
  components: {},
  methods: {
    selectType(type) {
      this.$emit('update-blaa', type);
    },
  },
};
  • Related