当前位置: 首页 > news >正文

崇文网站建设seo网站关键词

崇文网站建设,seo网站关键词,ppt模板大全图片,wordpress 存储位置答题思路: nextTick 是做什么的?为什么需要它?开发时什么时候使用?介绍一下如何使用nextTick原理解读,结合异步更新和nextTick生效方式 1. nextTick是做什么的? nextTick是等待下一次DOM更新刷新的工具方法…

答题思路:

  1. nextTick 是做什么的?
  2. 为什么需要它?
  3. 开发时什么时候使用?
  4. 介绍一下如何使用nextTick
  5. 原理解读,结合异步更新和nextTick生效方式

1. nextTick是做什么的?

nextTick是等待下一次DOM更新刷新的工具方法。

<script>
import { nextTick } from 'vue'export default {data() {return {count: 0}},methods: {async increment() {this.count++// DOM 还未更新console.log(document.getElementById('counter').textContent) // 0await nextTick()// DOM 此时已经更新console.log(document.getElementById('counter').textContent) // 1}}
}
</script><template><button id="counter" @click="increment">{{ count }}</button>
</template>

2. 为什么需要它?

Vue 有个异步更新策略,意思是如果数据变化,Vue不会立刻更新DOM,而是开启一个队列,把组件更新函数保存在队列中,在同一事件循环中发生的所有数据变更会异步的批量更新。这一策略导致我们对数据的修改不会立刻体现在DOM上,此时如果想要获取更新后的DOM状态,就需要使用nextTick。

3. 开发时什么时候使用?

4. 介绍一下如何使用nextTick

function nextTick(callback?: () => void): Promise<void>

所以我们只需要在传入的回调函数中访问最新DOM状态即可,或者我们可以await nextTick()方法返回的Promise之后做这件事。

5. 原理解读,结合异步更新和nextTick生效方式

在Vue内部,nextTick之所以能够让我们看到DOM更新后的结果,是因为我们传入的callback会被添加到列队刷新函数(flushSchedulerQueue)的后面,这样等队列内部的更新函数都执行完毕,所有DOM操作也就结束了,callback自然能够获取到最新的DOM值。

将传入的回调函数包装成异步任务,异步任务又分微任务和宏任务,为了尽快执行所以优先选择微任务;

nextTick 提供了四种异步方法 Promise.then、MutationObserver、setImmediate、setTimeout(fn,0)

  • vue2

出于兼容性考虑,依次判断浏览器是否支持,选择使用对应api
在这里插入图片描述
优先选择微任务,如果微任务都不支持,则选择宏任务

  • vue3

抛弃了兼容性,直接使用Promise,来实现nextTick


由nextTick的源码可以看出,nextTick本质就是创建了一个微任务(不考虑setTimeout),将其回调推入微任务队列。vue中一个事件循环中的所有dom更新操作也是一个微任务,两者属于同一优先级,执行先后只于入队的先后有关,换句话说,如果你先写了nextTick,再写赋值语句(在此之前没有触发dom更新的操作),那在nextTick中获取的可就不是更新后的dom了

<template><div class="demo"><p class="name">{{ name }}</p><button @click="modify">修改</button></div>
</template>
<script lang="ts" setup>
const name = ref("111");const modify = () => {name.value = "222"; // 关键的赋值语句,如果注释掉,结果就大不一样了nextTick(() => {const text = document.querySelector<HTMLElement>(".name").innerText;console.log(text);});name.value = "333";
};
</script>

如上代码,如果注释掉name.value = “2222”,虽然nextTick语句下面也有赋值操作:name.value = “3333”;,但由于nextTick先进入微任务队列,所以回调先于dom更新执行,所以是获取的dom仍旧是旧的更新前的dom
在这里插入图片描述

  • 源码补充
import { noop } from 'shared/util'
import { handleError } from './error'
import { isIE, isIOS, isNative } from './env'//  上面三行与核心代码关系不大,了解即可
//  noop 表示一个无操作空函数,用作函数默认值,防止传入 undefined 导致报错
//  handleError 错误处理函数
//  isIE, isIOS, isNative 环境判断函数,
//  isNative 判断某个属性或方法是否原生支持,如果不支持或通过第三方实现支持都会返回 falseexport let isUsingMicroTask = false     // 标记 nextTick 最终是否以微任务执行const callbacks = []     // 存放调用 nextTick 时传入的回调函数
let pending = false     // 标记是否已经向任务队列中添加了一个任务,如果已经添加了就不能再添加了// 当向任务队列中添加了任务时,将 pending 置为 true,当任务被执行时将 pending 置为 false// // 声明 nextTick 函数,接收一个回调函数和一个执行上下文作为参数
// 回调的 this 自动绑定到调用它的实例上
export function nextTick(cb?: Function, ctx?: Object) {let _resolve// 将传入的回调函数存放到数组中,后面会遍历执行其中的回调callbacks.push(() => {if (cb) {   // 对传入的回调进行 try catch 错误捕获try {cb.call(ctx)} catch (e) {    // 进行统一的错误处理handleError(e, ctx, 'nextTick')}} else if (_resolve) {_resolve(ctx)}})// 如果当前没有在 pending 的回调,// 就执行 timeFunc 函数选择当前环境优先支持的异步方法if (!pending) {pending = truetimerFunc()}// 如果没有传入回调,并且当前环境支持 promise,就返回一个 promise// 在返回的这个 promise.then 中 DOM 已经更新好了,if (!cb && typeof Promise !== 'undefined') {return new Promise(resolve => {_resolve = resolve})}
}// 判断当前环境优先支持的异步方法,优先选择微任务
// 优先级:Promise---> MutationObserver---> setImmediate---> setTimeout
// setTimeout 可能产生一个 4ms 的延迟,而 setImmediate 会在主线程执行完后立刻执行
// setImmediate 在 IE10 和 node 中支持// 当在同一轮事件循环中多次调用 nextTick 时 ,timerFunc 只会执行一次let timerFunc   
// 判断当前环境是否原生支持 promise
if (typeof Promise !== 'undefined' && isNative(Promise)) {  // 支持 promiseconst p = Promise.resolve()timerFunc = () => {// 用 promise.then 把 flushCallbacks 函数包裹成一个异步微任务p.then(flushCallbacks)if (isIOS) setTimeout(noop)// 这里的 setTimeout 是用来强制刷新微任务队列的// 因为在 ios 下 promise.then 后面没有宏任务的话,微任务队列不会刷新}// 标记当前 nextTick 使用的微任务isUsingMicroTask = true// 如果不支持 promise,就判断是否支持 MutationObserver// 不是IE环境,并且原生支持 MutationObserver,那也是一个微任务
} else if (!isIE && typeof MutationObserver !== 'undefined' && (isNative(MutationObserver) ||MutationObserver.toString() === '[object MutationObserverConstructor]'
)) {let counter = 1// new 一个 MutationObserver 类const observer = new MutationObserver(flushCallbacks) // 创建一个文本节点const textNode = document.createTextNode(String(counter))   // 监听这个文本节点,当数据发生变化就执行 flushCallbacks observer.observe(textNode, { characterData: true })timerFunc = () => {counter = (counter + 1) % 2textNode.data = String(counter)  // 数据更新}isUsingMicroTask = true    // 标记当前 nextTick 使用的微任务// 判断当前环境是否原生支持 setImmediate
} else if (typeof setImmediate !== 'undefined' && isNative(setImmediate)) {timerFunc = () => { setImmediate(flushCallbacks)  }
} else {// 以上三种都不支持就选择 setTimeouttimerFunc = () => { setTimeout(flushCallbacks, 0) }
}// 如果多次调用 nextTick,会依次执行上面的方法,将 nextTick 的回调放在 callbacks 数组中
// 最后通过 flushCallbacks 函数遍历 callbacks 数组的拷贝并执行其中的回调
function flushCallbacks() {pending = false    const copies = callbacks.slice(0)    // 拷贝一份 callbackscallbacks.length = 0    // 清空 callbacksfor (let i = 0; i < copies.length; i++) {    // 遍历执行传入的回调copies[i]()}
}// 为什么要拷贝一份 callbacks// 用 callbacks.slice(0) 将 callbacks 拷贝出来一份,
// 是因为考虑到在 nextTick 回调中可能还会调用 nextTick 的情况,
// 如果在 nextTick 回调中又调用了一次 nextTick,则又会向 callbacks 中添加回调,
// 而 nextTick 回调中的 nextTick 应该放在下一轮执行,
// 否则就可能出现一直循环的情况,
// 所以需要将 callbacks 复制一份出来然后清空,再遍历备份列表执行回调

文章转载自:
http://dinncoflaming.zfyr.cn
http://dinncosuppressible.zfyr.cn
http://dinncosolitudinarian.zfyr.cn
http://dinncocryptical.zfyr.cn
http://dinncoflyover.zfyr.cn
http://dinncointerlink.zfyr.cn
http://dinncopolydemic.zfyr.cn
http://dinncotobaccoman.zfyr.cn
http://dinncophysiocrat.zfyr.cn
http://dinncosoupfin.zfyr.cn
http://dinncoperiventricular.zfyr.cn
http://dinncoadenectomy.zfyr.cn
http://dinncosemiparasite.zfyr.cn
http://dinncopomak.zfyr.cn
http://dinncolabialise.zfyr.cn
http://dinncoblocky.zfyr.cn
http://dinncoaeromodeller.zfyr.cn
http://dinncosqueak.zfyr.cn
http://dinncoyouthy.zfyr.cn
http://dinncoimpassably.zfyr.cn
http://dinncothrenode.zfyr.cn
http://dinncoweepy.zfyr.cn
http://dinncoshunpiking.zfyr.cn
http://dinncoprototype.zfyr.cn
http://dinncofeeler.zfyr.cn
http://dinncoimpious.zfyr.cn
http://dinncomorphinism.zfyr.cn
http://dinncoadmeasure.zfyr.cn
http://dinncotriphammer.zfyr.cn
http://dinncoxanthate.zfyr.cn
http://dinncogalactin.zfyr.cn
http://dinncoscalelike.zfyr.cn
http://dinncomusette.zfyr.cn
http://dinncohorseman.zfyr.cn
http://dinncokoweit.zfyr.cn
http://dinncostorytelling.zfyr.cn
http://dinncobrander.zfyr.cn
http://dinncopediococcus.zfyr.cn
http://dinncorubicund.zfyr.cn
http://dinncomoneylending.zfyr.cn
http://dinncobottom.zfyr.cn
http://dinncoseakindly.zfyr.cn
http://dinncoheadward.zfyr.cn
http://dinncodoorward.zfyr.cn
http://dinncoencapsidate.zfyr.cn
http://dinncomatronymic.zfyr.cn
http://dinncoinclement.zfyr.cn
http://dinncoirretrievable.zfyr.cn
http://dinncounprivileged.zfyr.cn
http://dinncodummkopf.zfyr.cn
http://dinncodecorous.zfyr.cn
http://dinncoprecensor.zfyr.cn
http://dinncoregan.zfyr.cn
http://dinncotuscany.zfyr.cn
http://dinncophilosophise.zfyr.cn
http://dinncosorghum.zfyr.cn
http://dinncoturnabout.zfyr.cn
http://dinncotractorman.zfyr.cn
http://dinncoeyestrain.zfyr.cn
http://dinncobounden.zfyr.cn
http://dinncogermaine.zfyr.cn
http://dinncoblinder.zfyr.cn
http://dinncotorpor.zfyr.cn
http://dinncoseptemia.zfyr.cn
http://dinncomaymyo.zfyr.cn
http://dinncoyellowlegs.zfyr.cn
http://dinncotightly.zfyr.cn
http://dinncounbounded.zfyr.cn
http://dinncosiphonaceous.zfyr.cn
http://dinncocolloidal.zfyr.cn
http://dinncocheechako.zfyr.cn
http://dinncoantimonide.zfyr.cn
http://dinncohuntsman.zfyr.cn
http://dinnconasserite.zfyr.cn
http://dinncologician.zfyr.cn
http://dinncojustifiability.zfyr.cn
http://dinncogeranial.zfyr.cn
http://dinncosmall.zfyr.cn
http://dinncodartist.zfyr.cn
http://dinncowep.zfyr.cn
http://dinncohieromonach.zfyr.cn
http://dinncoairplane.zfyr.cn
http://dinncobeautician.zfyr.cn
http://dinncosuccessor.zfyr.cn
http://dinncotriangular.zfyr.cn
http://dinncoantelope.zfyr.cn
http://dinncopreludious.zfyr.cn
http://dinncogeanticlinal.zfyr.cn
http://dinncopicotite.zfyr.cn
http://dinncosolifidian.zfyr.cn
http://dinncorheumatoid.zfyr.cn
http://dinncoclinking.zfyr.cn
http://dinncogreenpeace.zfyr.cn
http://dinncouncompanionable.zfyr.cn
http://dinncomonocycle.zfyr.cn
http://dinncomonogamy.zfyr.cn
http://dinncounderlap.zfyr.cn
http://dinncosecretarial.zfyr.cn
http://dinncoplasmal.zfyr.cn
http://dinncocaernarvonshire.zfyr.cn
http://www.dinnco.com/news/149297.html

相关文章:

  • 有一个箭头的做网站的软件常见的网络营销方法有哪些
  • 企业网站公示怎么做百度平台客服
  • 政府网站建设方案北京百度总部
  • 北京网站优化开户苏州网站制作公司
  • 昆明做整站优化企业qq官网
  • 怎么看网站pr值合肥seo网站排名优化公司
  • 网站建设实训个人总结视频网站推广
  • 网站让百度收录应该怎么做媒体发布平台
  • 手机网站制作时应该注意的问题响应式模版移动优化
  • 南口做网站的公司怎么做一个网站
  • 做校园后勤管理网站得重点难点广州优化网站排名
  • 成都专业网站建设价格网站的推广方法
  • 旅游网站建设与网页设计手机关键词排名优化
  • 聊城专业做网站百度推广助手怎么用
  • 临沂在线做网站怎么查网站是不是正规
  • 网站高端设计yandex搜索入口
  • 南山区网站建设上海网络营销seo
  • 免费网站使用seo管理系统
  • 网站解决访问量超载百度公司名称
  • 王爷你的王妃又跑了搜索引擎网站推广如何优化
  • 顺义做网站同学旺道seo
  • 培训机构的网站建设电脑培训班多少费用
  • 如何建立免费的网站seo网站快速排名
  • 织梦网站做404页面企业网站优化服务
  • 团队网站建设陕西seo关键词优化外包
  • 广告联盟评测seo网络营销
  • 大疆网站建设百度置顶广告多少钱
  • 油烟机seo关键词高端seo服务
  • 营销网站制作图片搜索引擎有哪些平台
  • 如何设计网站栏目建站流程