Как стать автором
Обновить

Комментарии 5

Я правильно понимаю, что watch с immdiate и deep куда универсальней watchEffect?

Хотя-бы потому, что не нужна пляска с бубном с развертыванием отслежиемого объекта, если нужно следить за изменением внутри объекта (как в примере массив), мало того, используя $watch его можно точно также остановить через unwatch, плюсом можно получить предыдущее состояние объетка.

По-этому мне все еще не понятно зачем нужен watchEffect…

У watchEffect есть свои плюсы, например, он позволяет отслеживать сразу несколько переменных. Кроме того, благодаря свойствам flush, onTrack, onTrigger можно оптимизировать некоторые процессы вычислений, а также watchEffect предоставляет удобный метод для отмены асинхронных операций.

watch также может отслеживать несколько переменных, например через computed, или комплексную переменную

Ну вот разве что события, опять-же этого можно добиться в watch через nextTick нет?

Данный способ очень подробно описан в документации. Можно там посмотреть, как это правильно делается. На наш взгляд, способ слишком «костыльный», чтобы применять его на практике. Человек, который не знает этот нюанс или забыл, может не понять, что там происходит. WatchEffect позволяет сделать это более аккуратно, понятно и с меньшим количеством кода.

У вас написано:

WatchEffect может отслеживать только адрес памяти реактивного объекта. Изменение элементов массива или свойств объекта не изменит адрес памяти и, следовательно, не вызовет срабатывания метода watchEffect

Но после вы приводите примеры, где всё же изменение элементов массива или свойств объекта приводит к срабатыванию watchEffect. Получается всё же может отслеживать, но есть нюансы ;)

для слежения за массивами используйте спред-оператор, а для слежения за объектами — функцию toRefs().

Для объектов так же можно использовать (спред-оператор)[https://github.com/vuejs/core/issues/1351], НО! изменения будут отслеживаться поверхностно, как и в массивах на самом деле.

То есть если у вас массив:

const items = reactive([{ count: 0 }, { count: 10 }])
watchEffect(() => {
    console.log(...items)
})
items.push({ count: 15 }) // watchEffect сработает
items[0].count = 100 // watchEffect не сработает

Чтобы для такого массива watchEffect работал по аналогии с watch c флагом deep, нам нужно создать копию объекта и каждое свойство у него дёрнуть, что добавит в watchEffect отслеживание всех свойств. Если костылить, то можно дёрнуть cloneDeep из lodash :)

Зарегистрируйтесь на Хабре, чтобы оставить комментарий