Изменение значения внешней переменной, используемой в подпорках, после того, как прослушиватель вышел из компонента, отключает эффекты слушателя v-модели в Vue. js - PullRequest
1 голос
/ 17 января 2020

С учетом следующего HTML код:

<div id="app">
  <comp :is_checked="is_checked" v-on:ch="function(x){is_checked_2=x}"></comp>
  <p>{{ is_checked_2 }}</p>
</div>

<script src="app.js"></script>

и приложение. js:

var tm = `<div>
   <input type="checkbox" v-model="is_checked"
      v-on:change="$emit('ch',is_checked)"
   >{{ is_checked }}
</div>`

Vue.component('comp', {
  template: tm,
  props: ["is_checked"]
})

new Vue({
  el: "#app",
  data: function() {
    return { 
             is_checked: null,
             is_checked_2: null
           };
  }
});

Если мы заменим is_checked_2=x на console.log(x) в v-on:ch="function(x){...} все работает правильно и v-model меняется is_checked при изменении значения флажка ввода.

Также, если мы не отправляем значение переменной реквизитом и не определяем его локально в компоненте, все работает правильно.

Кажется, что изменение родительской Vue объектной переменной приводит к генерации всего HTML компонента, где значение переменной отправляется реквизитом, а переменная там сбрасывается сразу после запуска события внутри шаблона. Это вызывает то, что функции, вызванные событиями, не изменяют переменные компонента.

Это ошибка в Vue. js?



Чтобы сделать это более понятным, поведение выглядит следующим образом: изменение любого Vue родительского значения, которое не связано и, однако, связано с компонентом (без реквизита, без слотов), приводит к сбросу всех значений в компонент, который связан реквизитом. Следующее происходит только в том случае, если мы реактивно пишем в parent / main HTML, используя измененную родительскую переменную, мы можем добиться этого, поместив туда {{ .... }}. Кажется, это ошибка.

Пример: Vue имеет переменные a и b. Мы помещаем {{ a }} в основной код. Значение переменной b отправляется реквизитами компоненту и сопоставляется с переменной c. Со временем мы меняем это значение переменной c внутри компонента. В один момент мы решаем изменить значение a, и в результате оно «забывает» текущее состояние c и оно сбрасывается в исходное состояние вызванными подпорками.

Подводя итог: ошибка сама застревает что реквизиты должны вызываться реактивно только в случае изменения соответствующей родительской переменной, а не в случае изменения родительской переменной и изменения кода HTML.

Эта проблема не имеет ничего общего с прослушивателями событий нет событий, поскольку их можно тиражировать, не используя их.



Вывод: {{ is_checked_2 }} или {{ '',is_checked_2 }} или {{ '',console.log(is_checked_2) }} после изменения значения is_checked_2 вызывает повторную визуализацию всего верхнего Vue компонента, имеющего is_checked в качестве переменной, и сбрасывает переменную дочернего компонента, поскольку он имеет то же имя. Решение никогда не использует одно и то же имя для дочерних и родительских переменных компонента, связанных реквизитом. Это проблема архитектуры Vue / props, как она была спроектирована.

1 Ответ

0 голосов
/ 17 января 2020

Я не думаю, что это ошибка.

Скорее всего, вы столкнетесь с состоянием гонки, когда ваше change событие будет выполнено до или вместо внутренне подключенного один (отсюда, казалось бы, аннулированное связывание данных).

Поскольку v-model по сути является просто синтаксическим c сахаром для обновления данных о событиях пользовательского ввода. Цитирование документов :

v-model внутренне использует разные свойства и генерирует разные события для разных элементов ввода:

  • элементы text и textarea используют * Свойство 1022 * и событие input;
  • флажки и радиокнопки используют свойство checked и событие change;
  • поля выбора используют value в качестве опоры и change в качестве событие.

Возможно, вы также захотите увидеть « Пользовательская настройка компонента v-model».

...