Вуэйс. Мутация prop в дочернем компоненте не вызывает предупреждения. Интересно, почему


Вуэйс. Мутация prop в дочернем компоненте не вызывает предупреждения. Интересно, почему

27.11.2020 03:24:23 Просмотров 40 Источник

Я заметил что-то странное с мутацией prop (Vue 2.6).

Следует избегать мутации реквизита непосредственно в дочернем компоненте и это вызовет следующее известное предупреждение

"Избегайте прямого изменения опоры, так как значение будет перезаписано...."

Итак, если в моем родительском компоненте у меня есть такие данные, как

exemple: "Hello World"

это я передал как реквизит детскому компоненту. Если в этом дочернем компоненте я делаю что-то вроде

this.exemple = "Hello World!"

Я получаю предупреждение. Справедливо. Теперь я заметил, что если данные в Родительском объекте являются объектом типа

exemple : {message : "Hello World"}

и что в ребенке я делаю что-то подобное

this.exemple.message = "Hello World!"

Это не вызывает никакого предупреждения и более того данные в Родительском компоненте обновляются

Интересно, почему? Почему мутация prop распространяется на родителя в одном случае, но не в другом ? Может быть, это как-то связано с тем, как javascript хранит эти переменные ? Это хорошая практика, чтобы использовать этот трюк ?

У вопроса есть решение - Посмотреть?

Ответы - Вуэйс. Мутация prop в дочернем компоненте не вызывает предупреждения. Интересно, почему / Vuejs. Mutating prop in child component does not trigger warning. Wondering why

IVO GELOV

27.11.2020 04:03:30

Потому что профилактика мутаций улавливает только прямые назначения опоре-она не улавливает манипуляции ее свойствами. Идея заключается в том, что если вы присваиваете новые значения prop - вы присваиваете prop, а не переменной, которая находится в Родительском компоненте Vue, который питает prop.

Как только что - то в Родительском компоненте обновит переменную подачи-опора будет обновлена этим новым значением, и значение, которое вы присвоили опоре в вашем дочернем компоненте, будет перезаписано.

Если вы кормите опору объектом, а затем мутируете свойство внутри опоры в вашем дочернем компоненте - это повлияет на тот же объект внутри родительского компонента. Но если вы попытаетесь назначить новый объект реквизиту в вашем дочернем компоненте-вы должны получить то же самое предупреждение о мутировании реквизита.

Является ответом!
Dan

27.11.2020 04:09:08

Почему мутация prop распространяется на родителя в одном случае, но не в другом ? Может быть, это как-то связано с тем, как javascript хранит эти переменные ?

Да. Ссылочные переменные JavaScript, такие как объекты и массивы, не изменяют свои ссылки при изменении их свойств/значений. Это означает, что родитель также может получить доступ к измененным свойствам, поскольку он также имеет доступ к ссылке. И Vue только дает предупреждение о мутации prop, если ссылка изменяется.

Предупреждение:

this.prop = {}

Никакое предупреждение:

this.prop.id = 5

Это хорошая практика, чтобы использовать этот трюк ?

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


Хорошо, но почему Vue не предупреждает об этих изменениях?

Рассмотрим объект с 1000 свойствами или массив с 1000 элементами. Vue должен был бы глубоко проверить все 1000 изменений, и нет быстрого способа сделать это, потому что каждый элемент должен быть индивидуально сопоставлен со старым значением. Это будет иметь последствия для производительности и, вероятно, сделает многие приложения непригодными для использования.


Вот комментарий на эту тему от члена команды Vue Болеродана:

Как правило, вы не должны этого делать. Это может привести к неожиданным ошибкам в вашем коде. Как правило, вы должны сделать копию своего объекта, изменить его, а затем излучать вверх к родителю (как вы упомянули в своем последнем абзаце, я полагаю). Это метод, который я использую, и это общий консенсус подхода "сверху вниз" и "снизу вверх".

Satyam Pathak

27.11.2020 04:51:38

Очень простой ответ заключается в том, что вы мутируете reference value, и Vue не отслеживает весь reference, а только проверяет адрес, где находится ссылка. Поэтому, если вы повторно назначите это значение, оно предупредит вас.

Хорошим примером для понимания этого поведения является понимание через объявление переменной const

const делает вашу переменную неизменяемой, но опять же то же самое относится и к ней, если значение primitive в природе, вы не можете изменить его, но если это reference, вы не можете изменить его, но вы определенно можете обновить значение, расположенное в reference.

const a = 'Foo' // Primitive value

a = 'bar' // voilation
 
const b = { // Reference value
 name: 'Foo' 
}

b.name = 'Bar' // It's good

console.log(b)

b = {} // re-assign is voilation

Помочь в развитии проекта:
Закрыть X