Reputation: 2758
Is there an event in Vue that gets fired after an element re-renders? I have an object that updates, which causes my template to update. After it updates I want to trigger an event which runs a jQuery function. The code looks like this:
template: `
<div class="undo-margin">
<div class="gradient">
<img v-bind:src="blogPost.thumbnail"/>
<h1 class="align-bottom">{{blogPost.title}}</h1>
</div>
<div class="container bg-faded">
<article v-html="blogPost.article"></article>
</div>
</div>
`,
props: ["blogid"],
data: function () {
return blogPageData;
},
mounted: function () {
const blogid = jQuery("#blogPage").attr("blogid");
if (this.authdata.roles.indexOf("Administrator") !== -1) {
this.isAdmin = true;
}
this.getBlogPost(blogid);
},
methods: {
getBlogPost: function (blogid) {
var element = this;
$.ajax({
url: `/api/blog/${blogid}`,
type: "get",
headers: headers,
success: function (data) {
if (data === undefined) {
window.location.replace("/blog");
} else {
element.isDetails = true;
element.blogPost = data;
}
},
error: function (data) {
window.location.replace("/blog");
errorData.error = data.responseText;
}
});
}
},
watch: {
blogPost: function () {
console.log(this.blogPost);
jQuery("pre").each((i, e) => {
hljs.highlightBlock(e);
});
}
}
As you see, I tried using the watch event, however when the watch event triggers, my page is not updated yet. blogPost however has been changed, but vue is still rendering the page. I know I could theoretically fix this by adding a setTimeout, but I would prefer something cleaner.
Upvotes: 78
Views: 198868
Reputation: 178
If you are using Vue 3, you can utilize the nextTick() method. This method takes a callback, which will be called after the DOM has been updated due to a state change.
I have a similar situation where I need to trigger a change event on an element with jQuery on a legacy app. In my case I'm handling an event dispatched in a child component. Here's a rough example of my use case.
<template>
<childComponent @valueChanged="triggerElementChange"/>
<input ref="element" type="hidden" name="elementName"/>
</template>
<script setup>
import {ref, nextTick} from 'vue'
import ChildComponent from './ChildComponent'
// reference to element I want to trigger change on
// (identified by ref attribute with matching name)
const element = ref(null)
function triggerElementChange(){
// state updated via child component prior to emitting valueChanged event
// wait until DOM is updated, then trigger jQuery change event on referenced element
nextTick(() => {
$(element.value).change()
})
}
</script>
Upvotes: 1
Reputation: 862
updated() should be what you're looking for:
Called after a data change causes the virtual DOM to be re-rendered and patched.
The component’s DOM will have been updated when this hook is called, so you can perform DOM-dependent operations here.
Upvotes: 28
Reputation: 5835
updated
might be what you're looking for.
Vue2 https://v2.vuejs.org/v2/api/#updated
Edit: Now that Vue3 is the current version here are the links to the relevant lifecycle hooks.
Vue3 Composition API https://vuejs.org/api/composition-api-lifecycle.html#onupdated
Vue3 Options API https://vuejs.org/api/options-lifecycle.html#updated
Upvotes: 126