Vue – реактивный язык, то есть при изменении данных мы можем автоматически добиться их отображения в HTML. Чтобы помочь нам в этом, мы можем использовать наблюдатели в vue, чтобы следить за изменением данных, а затем что-то делать с HTML или отправлять пользователю сообщение об этом.
Это хорошо работает для простых наборов данных, но если мы начинаем иметь данные глубже одного уровня, становится сложнее следить за их изменениями.
Наблюдение за изменениями вложенных данных в Vue
Чтобы немного разобраться в этом вопросе, нам нужно понять, как работают наблюдатели в Vue. Например, ниже мы следим за изменениями в count
и console.log
этих изменений:
<script>
export default {
data() {
return {
count: 1
}
},
watch: {
count(data) {
console.log(data);
}
}
}
</script>
<template>
<h1>{{ count }}</h1>
<button @click="++this.count">
Click Me
</button>
</template>
Каждый раз, когда пользователь нажимает на кнопку, мы ++this.count
, а наш наблюдатель следит за любыми изменениями в count
. Затем он console
регистрирует данные, чтобы мы могли увидеть новое значение счета. Это означает, что каждый раз, когда нажимается кнопка, значение count отображается в журнале консоли.
Однако неглубокие изменения означают, что Vue проверяет только изменения в значении этого свойства. Если у нас есть данные глубиной более одного уровня, Vue не будет проверять обновления. Например, обновление count.number
ниже не вызовет наш наблюдатель для count
, поскольку Vue просто не проверяет изменения глубже, чем count
:
data() {
return {
count: {
number: 1,
type: 'number'
}
},
watch: {
// This doesn't get triggered when count.number!
count(data) {
console.log(data);
}
}
}
Вместо этого нам нужно указать, какой именно элемент изменяется. Мы можем продолжать следить за изменениями в count.number
выше, изменив наш наблюдатель на count.number
:
data() {
return {
count: {
number: 1,
type: 'number'
}
},
watch: {
// This gets triggered when count.number changes!
"count.number" : function(data) {
console.log(data);
}
}
}
Используя описанный выше метод, мы можем легко проверить изменения свойств внутри свойств, чтобы вызвать соответствующие наблюдатели, но это может быть очень сложно. Если мы хотим просто следить за изменениями count
, нам нужно использовать свойство deep.
Использование свойства deep
Свойство deep можно добавить к любому наблюдателю, и оно заставляет Vue следить за любым изменением в определенном свойстве данных. Это означает, что мы должны написать наш watcher
немного по-другому:
data() {
return {
count: {
number: 1,
type: 'number'
}
},
watch: {
count: {
handler(data) {
console.log(data);
},
deep: true
}
}
}
Теперь при изменении любого свойства в count
будет срабатывать наблюдатель count
. Когда мы console.log(data)
в этот раз, весь объект count
будет записан в консольный журнал, т.е. { number: 1, type: 'number' }
.
Это намного проще, чем нацеливаться на конкретные свойства внутри свойств, но это дорого. Поскольку Vue приходится каждый раз перебирать каждое свойство, это может вызвать серьезные проблемы с производительностью для очень больших объектов. Поэтому используйте этот способ только в том случае, если у вас есть известный объект небольшого размера. В других ситуациях используйте конкретные свойства, например count.number
.