С учетом следующего 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, как она была спроектирована.