vue的nexttick的作用(【Vue面试题】说说nextTick的使用和原理?)
分析
这道题及考察使用 ,有考察原理 ,nextTick在开发过程中应用的也较少 ,原理上和vue异步更新有密切关系 ,对于面试者考查很有区分度 ,如果能够很好回答此题 ,对面试效果有极大帮助 。
答题思路
nextTick是做什么的? 为什么需要它呢? 开发时何时使用它?抓抓头 ,想想你在平时开发中使用它的地方 下面介绍一下如何使用nextTick 原理解读 ,结合异步更新和nextTick生效方式 ,会显得你格外优秀回答范例:
nextTick是等待下一次DOM更新刷新的工具方法 。(其实一句话就可以把$nextTick这个东西讲明白:就是你放在 $ nextTick 当中的操作不会立即执行 ,而是等数据更新 、DOM更新完成之后再执行 ,这样我们拿到的肯定就是最新的了 。
再准确一点来讲就是 $nextTick方法将回调延迟到下次DOM更新循环之后执行 。(看不懂这句人话的 ,可以看上面)Vue有个异步更新策略,意思是如果数据变化 ,Vue不会立刻更新DOM ,而是开启一个队列,把组件更新函数保存在队列中 ,在同一事件循环中发生的所有数据变更会异步的批量更新 。这一策略导致我们对数据的修改不会立刻体现在DOM上 ,此时如果想要获取更新后的DOM状态 ,就需要使用nextTick 。
开发时 ,有两个场景我们会用到nextTick
created中想要获取DOM时; 响应式数据变化后获取DOM更新后的状态 ,比如希望获取列表更新后的高度 。nextTick类型
function nextTick(callback?: () => void): Promise<void>所以我们只需要在传入的回调函数中访问最新DOM状态即可 ,或者我们可以await nextTick()方法返回的Promise之后做这件事 。
在Vue内部 ,nextTick之所以能够让我们看到DOM更新后的结果 ,是因为我们传入的callback会被添加到队列刷新函数(flushSchedulerQueue)的后面 ,这样等队列内部的更新函数都执行完毕 ,所有DOM操作也就结束了 ,callback自然能够获取到最新的DOM值 。我们可以看一下官方的案例:
<script> import { nextTick } from vue export default { data() { return { count: 0 } }, methods: { async increment() { this.count++ // DOM 还未更新 console.log(document.getElementById(counter).textContent) // 0 await nextTick() // DOM 此时已经更新 console.log(document.getElementById(counter).textContent) // 1 } } } </script> <template> <button id="counter" @click="increment">{{ count }}</button> </template>给了一个count ,想要在界面中绑定展示 。一开始是0,如果用户点了increment ,希望这个count能够++ ,我们希望界面中能够变成1,可是在紧接着的console.log中你会发现它并没有更新 ,结果仍然为0 ,并不是1 ,那么怎么输出1呢?await nextTick() ,后面再输出结果就是1了 。为什么会这样呢?这就是nextTick()带给我们最关键的东西了 。说白了 ,就是nextTick()会返回一个promise ,未来在异步的方式再来调用我们这行代码。也就是说nextTick()下的console.log将来执行的时候我们的DOM已经更新了 。还有一种方式就是nextTick()中间加一个回调函数 ,在回调函数中输出我们的console.log里面的那一行代码 。这样也是可以的。
具体地源码分析可以看面试题:Vue中$nextTick原理:讲的很清晰
总结一下:就是 $nextTick将回调函数放到微任务或者宏任务当中以延迟它地执行顺序;重要的是理解源码中它的三个参数的意思:
callback:我们要执行的操作 ,可以放在这个函数当中 ,我们没执行一次$nextTick就会把回调函数放到一个异步队列当中; pending:标识 ,用以判断在某个事件循环中是否为第一次加入 ,第一次加入的时候才触发异步执行的队列挂载 timerFunc:用来触发执行回调函数 ,也就是Promise.then或MutationObserver或setImmediate 或setTimeout的过程理解之后,在看整个$nextTick里面的执行过程 ,其实就是把一个个 $nextTick中的回调函数压入到callback队列当中 ,然后根据事件的性质等待执行,轮到它执行的时候 ,就执行一下 ,然后去掉callback队列中相应的事件 。
面试版
说说nextTick吧nextTick:在下次DOM更新循环结束之后执行延迟回调 。
nextTick知道吗?这句话扩展开来说 ,就是由于Vue中DOM更新是「异步执行」的 ,即修改数据时 ,视图不会立即更新 ,而是会监听数据变化 ,并缓存在同一事件循环中 ,等同一数据循环中的所有数据变化完成之后 ,再统一进行视图更新 。经常我们会在还未更新的时候就使用了某个元素 ,这样是拿不到变更后的dom的,所以为了确保能够得到更新后的DOM,所以设置了nextTick()方法 。在修改数据之后立即使用这个方法 ,获取更新后的DOM 。简单概括 ,vue中的nextTick主要用于处理数据动态变化后,DOM还未及时更新的问题 ,用nextTick可以获取数据更新后最新dom的变化 。
在项目中什么时候用呢?比如 ,当我们需要在生命周期的created()函数进行一些DOM操作的时候一定 、要把相关代码放在Vue.nextTick()的回调函数中 。原因:在created钩子函数中,DOM还未进行任何渲染 ,此时进行DOM操作是没用的 ,所以如果要在这里操作dom,一定要将相关js代码放进
Vue.nextTick回调函数中 。又或者 ,在数据变化后要执行某个动作 ,而这个动作需要使用随数据变化而改变的DOM结构的时候 ,也需要把相关逻辑写入Vue.nextTick ()回调函数中 。 $nextTick既然把它传入的方法变成微任务了 ,那它和其它微任务的执行顺序是怎样的呢?这简单来说就是谁先挂载Promise对象的问题 ,在调用 $nextTick方法时就会将其闭包内部维护的执行队列挂载到Promise对象 ,在数据更新时Vue内部首先就会执行 $nextTick方法 ,之后便将执行队列挂载到了Promise对象上 ,其实在明白Js的Event Loop模型后 ,将数据更新也看做一个 $nextTick方法的调用 ,并且明白 $nextTick方法会一次性执行所有推入的回调,就可以明白执行顺序的问题了 。
$nextTick和nextTick区别$ nextTick和nextTick区别就是nextTick多了一个context参数 ,用来指定上下文 。但两个的本质是一样的 ,$nextTick是实例方法,nextTick是类的静态方法而已;实例方法的一个好处就是 ,自动给你绑定为调用实例的this罢了 。
创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!