# Методы экземпляра
# $watch
Аргументы:
{string | Function} source
{Function | Object} callback
{Object} options (опционально)
{boolean} deep
{boolean} immediate
{string} flush
Возвращает:
{Function} unwatch
Использование:
Отслеживание изменений реактивного свойства или функции вычисляемого свойства на экземпляре компонента. Коллбэк будет вызываться с новым и старым значением данного свойства. Можно указывать в виде строки только имена свойств верхнего уровня для
data
,props
илиcomputed
. Для более комплексных выражений или вложенных свойств следует использовать функцию.Пример:
const app = createApp({ data() { return { a: 1, b: 2, c: { d: 3, e: 4 } } }, created() { // имя свойства верхнего уровня this.$watch('a', (newVal, oldVal) => { // сделать что-нибудь }) // функция для отслеживания одного вложенного свойства this.$watch( () => this.c.d, (newVal, oldVal) => { // сделать что-нибудь } ) // функция для отслеживания сложного выражения this.$watch( // каждый раз, когда выражение `this.a + this.b` даёт другой // результат — будет вызываться коллбэк. Это похоже на отслеживание // вычисляемого свойства, но без необходимости его объявлять () => this.a + this.b, (newVal, oldVal) => { // сделать что-нибудь } ) } })
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37Если отслеживаемое значение является объектом или массивом, то любые изменения свойств или элементов в них не будут вызывать коллбэк, потому что они ссылаются на один и тот же объект/массив:
const app = createApp({ data() { return { article: { text: 'Vue is awesome!' }, comments: ['Indeed!', 'I agree'] } }, created() { this.$watch('article', () => { console.log('Заметка обновилась!') }) this.$watch('comments', () => { console.log('Комментарии обновились!') }) }, methods: { // Такие методы НЕ ВЫЗОВУТ коллбэк метода-наблюдателя, потому что // изменится только свойство объекта/массива, но не объект/массив целиком changeArticleText() { this.article.text = 'Vue 3 is awesome' }, addComment() { this.comments.push('New comment') }, // Такие методы ВЫЗОВУТ коллбэк метода-наблюдателя, потому что // заменяется объект/массив целиком changeWholeArticle() { this.article = { text: 'Vue 3 is awesome' } }, clearComments() { this.comments = [] } } })
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38Метод
$watch
возвращает функцию для остановки отслеживания:const app = createApp({ data() { return { a: 1 } } }) const vm = app.mount('#app') const unwatch = vm.$watch('a', cb) // ... позднее, останавливаем дальнейшее отслеживание unwatch()
1
2
3
4
5
6
7
8
9
10
11
12
13
14Опция: deep
Для отслеживания изменения вложенных значений внутри объектов нужно передавать
deep: true
в аргументе опций. Обратите внимание, опция не требуется для отслеживания мутаций массива.vm.$watch('someObject', callback, { deep: true }) vm.someObject.nestedValue = 123 // коллбэк будет вызван
1
2
3
4
5
6Опция: immediate
При передаче
immediate: true
в опциях, коллбэк будет вызываться незамедлительно с текущим значением отслеживаемого выражения:vm.$watch('a', callback, { immediate: true }) // `callback` будет вызван незамедлительно с текущим значением `a`
1
2
3
4
5Обратите внимание, при использовании опции
immediate
нет возможности остановить отслеживание при первом вызове коллбэка.// Подобное приведёт к ошибке const unwatch = vm.$watch( 'value', function() { doSomething() unwatch() }, { immediate: true } )
1
2
3
4
5
6
7
8
9При необходимости останавливать отслеживание в коллбэке следует сначала проверять его доступность:
let unwatch = null unwatch = vm.$watch( 'value', function() { doSomething() if (unwatch) { unwatch() } }, { immediate: true } )
1
2
3
4
5
6
7
8
9
10
11
12Опция: flush
Опция
flush
позволяет точнее контролировать время вызова коллбэка. Значением может быть'pre'
,'post'
или'sync'
.Значение по умолчанию
'pre'
. Это значит, что коллбэк должен быть вызван перед отрисовкой. Это позволяет в коллбэке обновить другие значения перед обновлением шаблона.Значение
'post'
можно использовать для отложенного вызова коллбэка по окончанию отрисовки. Его следует использовать, если в коллбэке требуется доступ к обновлённому DOM или дочерним компонентам через$refs
.При установке опции
flush
в значение'sync'
, коллбэк будет вызываться синхронно, как только значение изменится.Для значений
'pre'
и'post'
коллбэк будет буферизироваться с использованием очереди. Он будет добавлен в очередь только один раз, даже если отслеживаемое значение изменилось несколько раз. Промежуточные значения будут пропущены и не будут переданы в коллбэк.Буферизация коллбэка не только улучшает производительность, но и помогает обеспечить консистентность данных. Методы-наблюдатели не будут вызываться до тех пор, пока код занимающийся обновлением данных не завершится.
Значение
'sync'
нужно применять очень аккуратно, потому что у него нет этих преимуществ.Дополнительную информацию об опции
flush
можно изучить в разделе Синхронизация времени очистки эффектов.См. также: Методы-наблюдатели
# $emit
Аргументы:
{string} eventName
...args (опционально)
Генерирует событие на текущем экземпляре. Любые дополнительные аргументы будут переданы в коллбэк функции прослушивания.
Примеры:
Использование
$emit
только с указанием имени события:<div id="emit-example-simple"> <welcome-button v-on:welcome="sayHi"></welcome-button> </div>
1
2
3const app = createApp({ methods: { sayHi() { console.log('Привет!') } } }) app.component('welcome-button', { emits: ['welcome'], template: ` <button v-on:click="$emit('welcome')"> Кликни для приветствия </button> ` }) app.mount('#emit-example-simple')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18Использование
$emit
с дополнительными аргументами:<div id="emit-example-argument"> <advice-component v-on:advice="showAdvice"></advice-component> </div>
1
2
3const app = createApp({ methods: { showAdvice(advice) { alert(advice) } } }) app.component('advice-component', { emits: ['advise'], data() { return { adviceText: 'Какой-то совет' } }, template: ` <div> <input type="text" v-model="adviceText"> <button v-on:click="$emit('advice', adviceText)"> Кликни для получения какого-нибудь совета </button> </div> ` }) app.mount('#emit-example-argument')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26См. также:
# $forceUpdate
Использование:
Вызывает принудительную перерисовку экземпляра компонента. Обратите внимание, что он не затрагивает все дочерние компоненты, а только сам экземпляр и дочерние компоненты со вставленным содержимым в слот.
# $nextTick
Аргументы:
{Function} callback (опционально)
Использование:
Откладывает вызов коллбэка до следующего цикла обновления DOM. Используйте его сразу после изменения данных, чтобы дождаться обновления DOM. Аналогичен глобальному
nextTick
, за исключением того, что контекстthis
автоматически привязывается к экземпляру, вызвавшему этот метод.Пример:
createApp({ // ... methods: { // ... example() { // изменение данных this.message = 'changed' // DOM ещё не обновлён this.$nextTick(function() { // теперь DOM обновлён // `this` привязан к текущему экземпляру this.doSomethingElse() }) } } })
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16См. также: nextTick