Как включить отслеживание глубоких изменений в компонентах реквизита - PullRequest
0 голосов
/ 26 июня 2018

У меня есть компонент, который инициализируется так

<custom :opts="{map: false}"></custom>

и есть HTML, похожий на этот

<template id="custom">
    <div v-if="opts.map">
    I'm awesome
    </div>
    <button v-on:click="show"></button>
</template>

, где

function show(){
    this.opts = {map:true} // (1) <-- This is working and I could see hidden div
    this.opts.map = true // (2) <-- For some reason not working
    Vue.set(this.opts, 'map', true) // (3) <-- Still not working
}

Итак, мой вопрос: почему вариант 2 не работает и что я должен изменить, чтобы заставить мой элемент управления реагировать на сброс значения одним нажатием кнопки. Или правильное объяснение, почему (1) работает, а (2) - нет - также будет принято в качестве ответа.

Ответы [ 2 ]

0 голосов
/ 22 сентября 2018

Настоящая проблема с кодом (все 3 версии) заключается в изменении свойства компонента внутри компонента. В идиоматическом Vue только родитель должен изменять свойства. Если компонент должен произвести изменение, он должен передать событие родителю и позволить родителю внести необходимые изменения. В противном случае существует неоднозначность, в которой компонент «владеет» свойством.

Поток данных в один конец

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

Отправка сообщений родителям с событиями

0 голосов
/ 21 сентября 2018

Может быть неосновным здесь, но я считаю, что это происходит, потому что в компоненте vue props не реактивны, поэтому их объекты не наблюдаются в глубине. Или, скорее, они «немного реактивны», переназначение корневого подпорки действительно вызывает обновление DOM, но не ожидается, что оно будет выполнено вручную, и вы увидите предупреждение при выполнении этого при сборке разработки:

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

А почему реквизит не является полностью реактивным, во-первых: https://vuejs.org/v2/guide/components-props.html#One-Way-Data-Flow

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

...