Mutation observer
The v-mutate
directive utilizes the Mutation Observer API. It provides an easy to use interface for detecting when elements are updated.
Usage
v-mutate
is a simple interface for the Mutation Observer APIthat is implemented with Vue directives. There are two main ways to alter v-mutate
’s options; with directive modifiers using period notation, or with a custom options object. The following table contains information on the available directive modifiers:
Modifier | Default | Description |
---|---|---|
.attr | true | The attrmodifier monitors target node’s attribute changes |
.char | true | The charmodifier monitors changes to target node’s character data (and, its descendants if .sub is true ) |
.child | true | The childmodifier monitors for the addition or removal of child nodes (and, its descendants if .sub is true ) |
.sub | true | The submodifier extends all monitoring to the entire subtree of target node |
.once | undefined | The once modifier invokes the user provided callback one time and disconnects the observer |
.immediate | undefined | The immediate modifier invokes the user provided callback on mounted and does not effect .once |
By default, v-mutate
enables .attr
, .char
, .child
, and .sub
unless you manually apply one; in which case the undefined options are set to false:
<template>
<div>
<!-- attr, char, child, and sub are true -->
<div v-mutate="..." />
<!-- child is true, attr, char, and child are false -->
<div v-mutate.child="...">
</div>
</template>
In addition to the modifier syntax, the v-mutate
directive is configurable via a custom object containing a handler and options key. The following example demonstrates how both processes achieve the same result:
<template>
<div>
<div v-mutate="{
handler: onMutate,
modifiers: {
child: true,
sub: true,
}
}"
/>
<!-- is the same as -->
<div v-mutate.child.sub="onMutate" />
</div>
</template>
<script setup>
function onMutate () {
//
}
</script>
When using custom options, it’s recommended to use the .sub
modifier. This extends mutation monitoring to all descendants of the target element.
Once
There may be times where your callback should only fire once. In these scenarios, use the once option to disconnect the observer after the first detected mutation. In the next example, we bind data value content to 2 separate v-cardcomponents and an input
; then track the number of mutations that occur as we type:
<template>
<div>
<input type="text" v-model="content">
<v-card v-mutate="onMutate">{{ content }}</v-card>
<v-card v-mutate.once="onMutate">{{ content }}</v-card>
</div>
</template>
<script setup>
import { onMounted, shallowRef } from 'vue'
const content = shallowRef('Foo')
const mutations = shallowRef(0)
onMounted(() => {
content.value = 'Bar'
console.log(mutations.value) // 2
setTimeout(() => {
content.value = 'Foobar'
console.log(mutations.value) // 3
}, 200)
})
function onMutate () {
mutations.value++
}
</script>
When the value of content changes, both cards immediately call onMutate and iterate the value of the mutations data value. Because the second card is using the once modifier, it automatically unbinds its observer after the first change to content.
Immediate
Unlike the Intersection Observer API, the provided callback is not immediately invoked when a Mutation Observer is created. Vuetify normalizes this behavior with the immediate option. In the following example, the v-mutate
directive invokes the onMutate method when the element is initially mounted in the DOM and with every mutation; based upon the provided options.
<template>
<div v-mutate.immediate="onMutate">...</div>
</template>
<script setup>
import { onMounted, shallowRef } from 'vue'
const mutations = shallowRef(0)
onMounted(() => {
console.log(mutations.value) // 1
})
function onMutate () {
mutations.value++
}
</script>
The immediate callback is not counted as a mutation and does not trigger the observer to disconnect when using once.
API
Directive | Description |
---|---|
v-mutate | The mutation observer directive |