# Методы экземпляра
# $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 крутой!' }, comments: ['Да!', 'Согласен'] } }, created() { this.$watch('article', () => { console.log('Заметка обновилась!') }) this.$watch('comments', () => { console.log('Комментарии обновились!') }) }, methods: { // Такие методы НЕ ВЫЗОВУТ коллбэк метода-наблюдателя, потому что // изменится только свойство объекта/массива, но не объект/массив целиком changeArticleText() { this.article.text = 'Vue 3 крутой' }, addComment() { this.comments.push('Новый комментарий') }, // Такие методы ВЫЗОВУТ коллбэк метода-наблюдателя, потому что // заменяется объект/массив целиком changeWholeArticle() { this.article = { text: 'Vue 3 крутой' } }, 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
. Её можно также использовать и для отслеживания мутаций массива.Обратите внимание: при мутации (а не замене) объекта/массива и их отслеживании с помощью опции deep, старое значение будет таким же, как и новое, потому что они ссылаются на один и тот же объект/массив. Vue не хранит копию значения до мутации.
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