vue.nextTick()扒一扒它的底


前言

毕业一年,前端小白到技术大牛长路漫漫,写博客做总结真的是学习的一个好方法,在前端的路上,让我们一起成长进步,早日进大厂,实现自己事业的一片蓝天。
今天这篇文章讲一讲vue.nextTick()那些事,希望看到这篇文章的伙伴可以从中受益。


一、nextTick()是什么?

vue实现响应式并不是数据一发生变化就立即更新dom,而是按照一定的策略异步更新dom。下面附上vue官方文档的解释:

Vue 异步执行 DOM 更新。只要观察到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据改变。如果同一个 watcher 被多次触发,只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作上非常重要。然后,在下一个的事件循环“tick”中,Vue 刷新队列并执行实际 (已去重的) 工作。Vue 在内部尝试对异步队列使用原生的 Promise.thenMessageChannel,如果执行环境不支持,会采用setTimeout(fn, 0)代替。

例如,当你设置vm.someData = 'new value',该组件不会立即更新渲染。当刷新队列时,组件会在事件循环队列清空时的下一个“tick”更新。多数情况我们不需要关心这个过程,但是如果你想在DOM状态更新后做点什么,这就可能有些棘手。虽然Vue.js通常鼓舞开发人员沿着“数据驱动”的方式思考,避免直接操作DOM,但是有时候我们确实需要这么做。为了在数据变化后等待Vue完成更新DOM,可以在数据变化之后立即使用Vue.nextTick(callback)。这样回调函数会在DOM更新之后调用。

举一个栗子:

<template>
<div id="app">
    <div ref="ref1">This is {{msg1}}</div>
    <div ref="ref2">This is {{msg2}}</div>
    <button @click="update">update</button>
</div>
</template>
<script>
new Vue({
    el:"#app",
    data: {
        msg1: 'oldValue1',
        msg2: 'oldValue2'
    },
    methods: {
        update() {
            this.msg1 = "newValue1";
            this.msg2 = "newValue2";
            console.log(this.$refs.ref1.innerText);
            this.nextTick(() => {
                console.log(this.$refs.ref2.innerText);
            })
        },
    }
})
</script>
//This is oldValue1
//This is newValue2

可以看到,msg1显示的内容还是之前的,但是msg2显示的内容是更新之后的。

二、nextTick()使用场景和原因

1.created()钩子函数

在Vue生命周期的created()钩子函数中进行DOM操作一定要放在Vue.nextTick()的回调函数中。

原因: created()阶段已经完成:数据观测,属性和方法的运算,watch/event事件回调。然而挂载阶段还未开始,$el属性还不可见。所以DOM还未进行任何渲染,如果此时操作DOM无异于徒劳,所以如果要在created()里面操作DOM一定要放在Vue.nextTick()回调函数中执行。在mounted()钩子函数中,DOM已经完成挂载和渲染,所以此时操作DOM不会出现任何问题。

created() {
    this.nextTick(() => { //不使用Vue.nextTick()会报错
        this.$refs.ref1.innerText="created中更改了内容";
    })
}

2.数据变化之后,你想立即使用js操作新的视图做点什么的时候

代码如下(示例):

<template>
<div id="app">
    <div ref="ref1">This is {{msg1}}</div>
    <div ref="ref2">This is {{msg2}}</div>
    <button @click="update">update</button>
</div>
</template>
<script>
new Vue({
    el:"#app",
    data: {
        msg1: 'oldValue1',
        msg2: 'oldValue2'
    },
    methods: {
        update() {
            this.msg1 = "newValue1";
            this.msg2 = "newValue2";
            console.log(this.$refs.ref1.innerText);
            this.nextTick(() => {
                console.log(this.$refs.ref2.innerText);
            })
        },
    }
})
</script>
//This is oldValue1
//This is newValue2

总结

Vue的dom更新是异步的。在数据改变之后,视图会在DOM下一次更新之后才会获得相应更新。如果要基于新试图做点什么的话,要放在Vue.nextTick()回调函数中执行。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值