[Vuejs]-Can i change component prop variable binded to another variable in VueJS

0👍

For your situation you can simply use .sync modifier to avoid mutating props directly. Sync modifier means your prop receiver component (child) receives props data from parent and generates an event when parent must change passed value.
And parent component should bind prop with ‘.sync’ modifier that means auto subscription on child event with update.
More info you can read here

This way your code will work fine

Vue.component('like',{
    template: '#like' ,
    props: ['lval','lname','lstep','lclass'],
    methods:{
        changeCounter : function(step){
            this.$emit('update:lval', this.lval + parseInt(step));
        }
    }
});
new Vue({
    el: '#app',
    data:{
        counterlike: 0,
        counterdislike: 0
    }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
        <like lname="Like" lstep="1" :lval.sync="counterlike" lclass="btn-success"></like>
        <like lname="Dislike" lstep="-1" :lval.sync="counterdislike" lclass="btn-danger"></like>
        <br>
        {{ counterlike + counterdislike }}
    </div>

    <template id="like">
        <button :class="['btn',lclass]" @click="changeCounter(lstep)" >{{ lname + ' ' + lval }}</button>
    </template>

0👍

There is a reason why props can’t be mutated directly, this way the information has one-way flow, from parent to child and not the other way around.

See: One Way Data Flow

0👍

True two-way bindings can’t be achieved, but the child can emit an event with needed info to the parent, and the latter could update bound variable.

Since 2.3.0 Vue has a special .sync modifier to do just that, and here is your modified snippet using .sync modifier. Note, that changeCounter method doesn’t change lval directly, but emits an event.

Here

Vue.config.productionTip = false;
Vue.component('like', {
  template: '#like',
  props: ['lval', 'lname', 'lstep', 'lclass'],
  methods: {
    changeCounter: function(step) {
      const newlval = this.lval + parseInt(step);
      this.$emit('update:lval', newlval);
    }
  }
});
new Vue({
  el: '#app',
  data: {
    counterlike: 0,
    counterdislike: 0
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <like lname="Like" lstep="1" :lval.sync="counterlike" lclass="btn-success"></like>
  <like lname="Dislike" lstep="-1" :lval.sync="counterdislike" lclass="btn-danger"></like>
  <br> {{ counterlike + counterdislike }}
</div>

<template id="like">
  <button :class="['btn',lclass]" @click="changeCounter(lstep)" >{{ lname + ' ' + lval }}</button>
</template>
👤Styx

Leave a comment