Skip to content

Document why watched template refs require theflush: 'post' option to be set #816

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jan 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions src/guide/composition-api-template-refs.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,66 @@ Composition API template refs do not have special handling when used inside `v-f
}
</script>
```

## Watching Template Refs

Watching a template ref for changes can be an alternative to the use of lifecycle hooks that was demonstrated in the previous examples.

But a key difference to lifecycle hooks is that `watch()` and `watchEffect()` effects are run *before* the DOM is mounted or updated so the template ref hasn't been updated when the watcher runs the effect:

```vue
<template>
<div ref="root">This is a root element</div>
</template>

<script>
import { ref, watchEffect } from 'vue'

export default {
setup() {
const root = ref(null)

watchEffect(() => {
// This effect runs before the DOM is updated, and consequently,
// the template ref does not hold a reference to the element yet.
console.log(root.value) // => null
})

return {
root
}
}
}
</script>
```

Therefore, watchers that use template refs should be defined with the `flush: 'post'` option. This will run the effect *after* the DOM has been updated and ensure that the template ref stays in sync with the DOM and references the correct element.

```vue
<template>
<div ref="root">This is a root element</div>
</template>

<script>
import { ref, watchEffect } from 'vue'

export default {
setup() {
const root = ref(null)

watchEffect(() => {
console.log(root.value) // => <div></div>
},
{
flush: 'post'
})

return {
root
}
}
}
</script>
```

* See also: [Computed and Watchers](./reactivity-computed-watchers.html#effect-flush-timing)
2 changes: 1 addition & 1 deletion src/guide/reactivity-computed-watchers.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ In this example:
- The count will be logged synchronously on initial run.
- When `count` is mutated, the callback will be called **before** the component has updated.

In cases where a watcher effect needs to be re-run **after** component updates, we can pass an additional `options` object with the `flush` option (default is `'pre'`):
In cases where a watcher effect needs to be re-run **after** component updates (i.e. when working with [Template Refs](./composition-api-template-refs.md#watching-template-refs)), we can pass an additional `options` object with the `flush` option (default is `'pre'`):

```js
// fire after component updates so you can access the updated DOM
Expand Down