记录一下 Vue.$nextTick 的使用经历
首先看一下官方文档介绍
官方介绍似乎有点模糊,通俗点来说,Vue.$nextTick() Api中,参数是一个回调函数,可以在它的回调函数中进行一些操作。Api的作用是等到所有的DOM更新完毕之后,在进行Api中回调函数里面的操作
通常使用的地方是渲染数据到DOM,在数据渲染到页面完成前,如果直接修改DOM中的例如样式等属性,数据渲染完成后样式是不会生效的,这时候就需要用到 $nextTick() Api,这样会在所有的DOM渲染完成后再去修改一些DOM中渲染数据的属性
看一个最近项目的例子,将后台返回的富文本展示在页面,查看详情,富文本内容大概如下
会返回一串HTML代码,其中会有img标签的图片
而这些img标签是没有样式的(行内元素,宽高默认图片大小),展示效果在一个弹窗中,所以要给所有的img标签添加样式
display: block;
width: 100%;
宽度100%,高度自适应,这样展示出效果不会影响布局,所以…上代码
<template>
<div id="contentDetail">
<el-dialog title="资讯详情" :visible="contentDetailIsShow" @update:visible="v => $emit('update:contentDetailIsShow', v)" width="25%">
<!-- 这边是将文章详情页面做成组件,newsInfo是父组件传来的详情信息,通过ref获取到DOM -->
<div id="news_box" v-html="newsInfo.content" ref="news_box"></div>
</el-dialog>
</div>
</template>
<script>
export default {
name: "contentDetail",
props: {
// 弹窗显示隐藏
contentDetailIsShow: {
type: Boolean,
default: false
},
// 文章信息
newsInfo: {
type: Object,
default: () => {
return {}
}
}
},
methods: {
// 递归查询img标签,给标签添加样式
selectImg(Node){
if(Node.childNodes){
for(let i = 0;i < Node.childNodes.length;i ++){
if(Node.childNodes[i].tagName == 'IMG'){
// 这边给所有文章里面的img标签添加样式
Node.childNodes[i].style.display = 'block'
Node.childNodes[i].style.width = '100%'
}else{
this.selectImg(Node.childNodes[i])
}
}
}
}
},
mounted() {
// 渲染完成后调用方法修改图片样式
this.$nextTick(() => {
this.selectImg(this.$refs.news_box)
})
}
}
</script>
<style scoped lang="scss">
#news_box{
width: 100%;
overflow-y: auto;
height: 400px;
}
</style>
页面效果
去掉 $nextTick() 看一下效果
mounted() {
this.selectImg(this.$refs.news_box)
}
可以看到图片变成自己默认的样式,宽度很宽,盒子变形容不下,就是因为 mounted中执行方法修改img标签样式时,页面还没有img标签,所以当渲染完成后发现样式并没有改变,这时候就需要使用 Vue.$nextTick(),所有的DOM都渲染完成后,再去递归查询文章里面的img标签,修改他们的样式。
记得点赞