Могу ли я изменить переменную пропеллера компонента, привязанную к другой переменной в VueJS - PullRequest
0 голосов
/ 22 февраля 2019

Я начал изучать vuejs и хотел создать простой проект «like», используя компоненты vuej.Я сделал две кнопки (нравится и не нравится), что у каждого есть отдельный счетчик.До сих пор все было в порядке.Теперь я хочу показать сумму этих счетчиков в под.для этого мне нужны эти 2 переменные рядом друг с другом вне компонента, поэтому я пытаюсь связать их значения с внешними переменными. Но внешние переменные не изменились!и также сказал в консоли:

[Vue warn]: избегайте прямого изменения свойства, так как значение будет перезаписываться всякий раз, когда родительский компонент перерисовывается.Вместо этого используйте данные или вычисляемое свойство, основанное на значении реквизита.Мутация опоры: "lval" найден в --->

См. Мой код:

Vue.component('like',{
    template: '#like' ,
    props: ['lval','lname','lstep','lclass'],
    methods:{
        changeCounter : function(step){
            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="counterlike" lclass="btn-success"></like>
        <like lname="Dislike" lstep="-1" :lval="counterdislike" lclass="btn-danger"></like>
        <br>
        {{ counterlike + counterdislike }}
    </div>

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

Ответы [ 3 ]

0 голосов
/ 22 февраля 2019

True двусторонние привязки не могут быть достигнуты, но дочерний элемент может передать событие с необходимой информацией родительскому элементу, и последний может обновить связанную переменную.

Начиная с 2.3.0 Vue имеет специальный .sync модификатор , чтобы сделать это, и вот ваш модифицированный фрагмент с использованием модификатора .sync.Обратите внимание, что метод changeCounter не изменяет lval напрямую, а генерирует событие.

Здесь

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>
0 голосов
/ 22 февраля 2019

В вашей ситуации вы можете просто использовать модификатор .sync, чтобы избежать мутации напрямую.Модификатор Sync означает, что ваш компонент приемника prop (child) получает данные props от parent и генерирует событие, когда parent должен изменить переданное значение.И родительский компонент должен связывать проп с модификатором .sync, что означает автоматическую подписку на дочернее событие с обновлением.Больше информации вы можете прочитать здесь

Таким образом, ваш код будет работать нормально

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 голосов
/ 22 февраля 2019

Существует причина, по которой реквизит нельзя мутировать напрямую, так как информация имеет односторонний поток, от родителя к ребенку, а не наоборот.

См .: One WayПоток данных

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...