今天的主角是nextTick,它是Vue官方提供的一个API。
首先在介绍它之前,我们要先了解一件事。
可能你还没有注意到,Vue 在更新 DOM 时是异步执行的。只要侦听到数据变化,Vue将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更。如果同一个 watcher 被多次触发,只会被推入到队列中一次。
这是Vue官方文档中对Vue异步更新DOM队列的简单介绍。
其实我们就知道一件事情就可以,Vue在更新DOM的时候是异步执行的。什么是异步大家应该都知道,不知道的可以翻看一下我前面的博客。
异步执行的坏处是什么,就是可能我们在需要使用DOM的时候,它还在加载中,并没有实际更新,而是更新的它前面的操作,或者后面的操作。
反正就是,会导致我们无法正常获取DOM的更新结果。
我们先举一个简单的例子看一下吧。
<div id="app">
{
{message}}
</div>
<script>
const vm = new Vue({
el:'#app',
data:{
message:'Ray'
}
});
vm.message = 'CreatorRay';
console.log(vm.$el.textContent);
</script>
我们写了一个简单的vue实例vm,然后通过操作vm对象改变它内部的data值,把message由Ray改为CreatorRay。
然后通过vm.$el.textContent获取一下更新后的内容。
我们看一下结果:
vm.$el.textContent的内容是Ray。
这说明了啥,我们并没有获取到更新后的数据。这就是Vue异步渲染DOM的结果。
这就很难受了,可能阻碍我们进行实际的逻辑开发。
所以,nextTick这个API的作用就来了。
现在我们加入下面这段代码:
Vue.nextTick(()=> {
console.log(vm.$el.textContent);
});
再看一下页面渲染后的控制台。
这样我们就能获取到实际的数据更新的结果了。
这只是一个最简单的nextTick的使用
下面我们以一个真实的开发需求,看一下nextTick在开发中的实际应用。
需求:
我们现在有一个已经开发好的弹窗组件,弹窗触发的条件由后端提供。也就是说,弹窗什么时候触发,完全由后端提供的数据决定。
<div id="app">
<App></App>
</div>
<script>
const Pop = {
data () {
return {
isShow:false
}
},
props:{
name:{
type:String,
default:''
}
},
template:`
<div v-if='isShow'>
{
{name}}
</div>
`,
methods: {
show(){
if(this.name == '触发'){
this.isShow = true; // 弹窗组件展示
}
console.log(this.name);
}
}
}
const App = {
data () {
return {
name:'不触发'
}
},
created () {
// 模拟异步请求
setTimeout(()=>{
// 数据更新
this.name = '触发';
this.$refs.pop.show();
/*this.$nextTick(()=> {
this.$refs.pop.show();
})*/
},1000)
},
components: {
Pop
},
template:`<Pop ref='pop' :name='name' ></Pop>`
}
new Vue({
el:'#app',
data:{
},
components:{
App
}
});
</script>
代码我就简单意思了一下。
一个局部组件Pop充当我们的弹窗组件。一个局部组件App,在App组件中,使用Pop,并且给Pop组件写了ref属性,并且通过父子组件通信,给子组件传了一组名字为name的值,这个name就是触发弹窗组件的条件。
然后看一下App组件的created生命周期钩子内,我们模拟一下对后端接口的请求,我为了节约时间,就通过setTimeout在模拟一下异步请求。
假设我们获取到的数据name为触发,我们通过this.name=‘触发’。对现有数据进行一下更新。name为触发,就是触发弹窗组件的条件。现在我们要触发一下子组件Pop的show方法。正好我们给Pop组件挂载了ref属性,可以直接获取到Pop组件对象,调用它的方法,非常好,我们现在通过常规的方法,看看能不能成功。
直接通过this.$refs.pop.show()调用子组件的方法。
看一下结果:
确实成功调用了子组件的show方法,但是show方法中输出的name值为不触发,而且页面上的内容也没有渲染出来。这说明我们在setTimeout中修改name值的操作,并没有及时对子组件进行更新。
ok,接下来我们试一下nextTick。
先注释一下this.$refs.pop.show();
在下面加上这段代码:
this.$nextTick(()=> {
this.$refs.pop.show();
})
现在看一下结果:
show方法中输出的name值为触发,并且页面上的”弹窗内容“也进行了渲染。
okkkkkk,非常的棒。
这就是nextTick在我们实际的业务开发中的应用,还是非常好用的。
虽然vue建议我们使用“数据驱动”的方式思考,避免直接接触 DOM,但是有时我们必须要这么做。nextTick就是我们的好帮手。
有微信小程序课设、毕设需求联系个人QQ:505417246
关注下面微信公众号,可以领取微信小程序、Vue、TypeScript、前端、uni-app、全栈、Nodejs、Python等实战学习资料
最新最全的前端知识总结和项目源码都会第一时间发布到微信公众号,请大家多多关注,谢谢!