一、HTML与DOM
HTML代码:
<div>
<h1>My title</h1>
Some text content
<!-- TODO: Add tagline -->
</div>
DOM节点树:
二、DOM异步渲染和nextTick
内容来自博客个人理解this.$nextTick()的使用场景
最近有在一个老项目的html页面中使用vue和echarts,点击按钮后需要重新渲染echart图标,但是echart却报错:Can’t get dom width or height。可以很清楚知道是由于echarts获取不到宽度和高度,我试过使用this.refs来过去元素的宽高,但还是失败了,所以,我觉得还是dom渲染问题,那么此时快速的解决办法就是使用this.nextTick()方法。
我从上面的使用结果可以知道,this.nextTick()方法主要是用在随数据改变而改变的dom应用场景中,vue中数据和dom渲染由于是异步的,所以,要让dom结构随数据改变这样的操作都应该放进this.nextTick()的回调函数中。created()中使用的方法时,dom还没有渲染,如果此时在该钩子函数中进行dom赋值数据(或者其它dom操作)时无异于徒劳,所以,此时this.$nextTick()就会被大量使用,而与created()对应的是mounted()的钩子函数则是在dom完全渲染后才开始渲染数据,所以在mounted()中操作dom基本不会存在渲染问题。
示例
<div class="app">
<div ref="msgDiv">{{msg}}</div>
<div v-if="msg1">Message got outside $nextTick: {{msg1}}</div>
<div v-if="msg2">Message got inside $nextTick: {{msg2}}</div>
<div v-if="msg3">Message got outside $nextTick: {{msg3}}</div>
<button @click="changeMsg">
Change the Message
</button>
</div>
new Vue({
el: '.app',
data: {
msg: 'Hello Vue.',
msg1: '',
msg2: '',
msg3: ''
},
methods: {
changeMsg() {
this.msg = "Hello world."
this.msg1 = this.$refs.msgDiv.innerHTML
this.$nextTick(() => {
this.msg2 = this.$refs.msgDiv.innerHTML
})
this.msg3 = this.$refs.msgDiv.innerHTML
}
}
})
点击前
点击后
结果
从上图可知,vue中的msg1和msg3显示的数据还是赋值之前的,msg2显示的数据则是赋值之后的。其根本原因是vue中的dom渲染是异步的。