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

专业网站制作案例免费的外网连接器

专业网站制作案例,免费的外网连接器,平面设计素材网,有没有做公司网站的目录 前言一、Vue异步更新队列二、nextTick 用法三、原理分析四、nextTick 源码解析1#xff09;环境判断2#xff09;nextTick() 五、补充 前言 在我们使用Vue的过程中#xff0c;基本大部分的 watcher 更新都需要经过 异步更新 的处理。而 nextTick 则是异步更新的核心。… 目录 前言一、Vue异步更新队列二、nextTick 用法三、原理分析四、nextTick 源码解析1环境判断2nextTick() 五、补充 前言 在我们使用Vue的过程中基本大部分的 watcher 更新都需要经过 异步更新 的处理。而 nextTick 则是异步更新的核心。 官方对其的定义: 在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法获取更新后的 DOM。 一、Vue异步更新队列 Vue 可以做到 数据驱动视图更新我们简单写一个案例实现下 templateh1 styletext-align:center clickhandleCount{{ value }}/h1 /templatescript export default {data () {return {value: 0}},methods: {handleCount () {for (let i 0; i 10; i) {this.value iconsole.log(this.value)}}} } /scriptvue异步更新dom 当我们触发这个事件视图中的 value 肯定会发生一些变化。 这里可以思考下Vue是如何管理这个变化的过程呢比如上面这个案例value 被循环了10次那 Vue 会去渲染dom视图10次吗显然是不会的毕竟这个性能代价太大了。其实我们只需要 value 最后一次的赋值。 实际上 Vue 是 异步更新 视图的也就是说等 handleCount() 事件执行完检查发现只需要更新 value然后再一次性更新数据和Dom避免无效更新。 总之Vue 的 数据更新 和 DOM更新 都是异步的Vue 会将数据变更添加到队列中在下一个事件循环中进行批量更新然后异步地将变更应用于实际的 DOM 元素以保持视图与数据的同步。 Vue官方文档也印证了我们的想法如下 Vue 在更新 DOM 时是 异步 执行的。只要侦听到 数据变化 Vue 将开启一个队列并缓冲在同一事件循环中发生的所有数据变更。如果同一个 watcher 被多次触发只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作是非常重要的。然后在下一个的事件循环“tick”中Vue 刷新队列并执行实际 (已去重的) 工作。 详细可见Vue官方文档 - 异步更新队列 二、nextTick 用法 看例子比如当 DOM 内容改变后我们需要获取最新的元素高度。 templatediv{{ name }}/div /templatescript export default {data () {return {name: }},methods: {},mounted () {console.log(this.$el.clientHeight)this.name 铁锤妹妹console.log(this.name, name)console.log(this.$el.clientHeight)this.$nextTick(() {console.log(this.$el.clientHeight)})} } /script从打印结果可以看出name数据虽然更新了但是前两次元素高度都是0只有在 nextTick 中才能拿到更新后的 Dom 值具体是什么原因呢下面就分析下它的原理吧。 这个实例也可参考学习watch监听和$nextTick结合使用处理数据渲染完成后的操作方法 三、原理分析 在执行 this.name 铁锤妹妹 的时候就会触发 Watcher 更新watcher 会把自己放入一个队列。 // src/core/observer/watcher.ts update () {if (this.lazy) {// 如果是计算属性this.dirty true} else if (this.sync) {// 如果要同步更新this.run()} else {// 将 Watcher 对象添加到调度器队列中以便在适当的时机执行其更新操作。queueWatcher(this)} }用队列的原因是比如多个数据变更直接更新视图多次的话性能就会降低所以对视图更新做一个异步更新的队列避免不必要的计算和 DOM 操作。在下一轮事件循环的时候刷新队列并执行已去重的工作nextTick的回调函数组件重新渲染更新视图。 然后调用 nextTick() 响应式派发更新的源码如下 // src/core/observer/scheduler.tsexport function queueWatcher(watcher: Watcher) {// ...// 因为每次派发更新都会引起渲染所以把所有 watcher 都放到 nextTick 里调用nextTick(flushSchedulerQueue) }function flushSchedulerQueue () {queue.sort(sortCompareFn)for (index 0; index queue.length; index) {watcher queue[index]watcher.run()// ...省略细节代码} }这里参数 flushSchedulerQueue 方法就会被放入事件循环主线程任务执行完之后就会执行这个函数对 watcher 队列排序、遍历、执行 watcher 对应的 run() 方法然后render更新视图。 也就是说 this.name 铁锤妹妹 的时候任务队列简单理解成这样 [flushSchedulerQueue] 。 下一行 console.log(this.name, name) 检验下 name 数据是否更新。 然后下一行 console.log(this.$el.clientHeight) 由于更新视图任务 flushSchedulerQueue 在任务队列中还没有执行所以无法拿到更新后的视图。 然后执行 this.$nextTick(fn) 时候添加一个异步任务这时任务队列简单理解成这样 [flushSchedulerQueue, fn] 。 然后 同步任务 都执行完毕接着按顺序执行任务队列中的 异步任务。第一个任务执行就会更新视图后面自然能得到更新后的视图了。 四、nextTick 源码解析 1环境判断 主要判断用哪个宏任务或者微任务因为宏任务耗费时间大于微任务所以优先使用 微任务判断顺序如下 Promise 》 MutationObserver 》 setImmediate 》 setTimeout // src/core/util/next-tick.tsexport let isUsingMicroTask false // 是否启用微任务开关const callbacks: ArrayFunction [] //回调队列 let pending false // 异步控制开关标记是否正在执行回调函数// 该方法负责执行队列中的全部回调 function flushCallbacks() {// 重置异步开关pending false// 防止nextTick里有nextTick出现的问题// 所以执行之前先备份并清空回调队列const copies callbacks.slice(0)callbacks.length 0// 执行任务队列for (let i 0; i copies.length; i) {copies[i]()} }// timerFunc就是nextTick传进来的回调等... 细节不展开 let timerFunc // 判断当前环境是否支持原生 Promise if (typeof Promise ! undefined isNative(Promise)) {const p Promise.resolve()timerFunc () {p.then(flushCallbacks)if (isIOS) setTimeout(noop)}isUsingMicroTask true } else if (!isIE typeof MutationObserver ! undefined (isNative(MutationObserver) ||// PhantomJS and iOS 7.xMutationObserver.toString() [object MutationObserverConstructor]) ) {// 当原生 Promise 不可用时timerFunc 使用原生 MutationObserver// MutationObserver不要在意它的功能其实就是个可以达到微任务效果的备胎let counter 1const observer new MutationObserver(flushCallbacks)const textNode document.createTextNode(String(counter))observer.observe(textNode, {characterData: true})timerFunc () {// 使用 MutationObservercounter (counter 1) % 2textNode.data String(counter)}isUsingMicroTask true } else if (typeof setImmediate ! undefined isNative(setImmediate)) {// 使用setImmediate虽然也是宏任务但是比setTimeout更好timerFunc () {setImmediate(flushCallbacks)} } else {// 最后的倔强timerFunc 使用 setTimeouttimerFunc () {setTimeout(flushCallbacks, 0)} }然后进入核心的 nextTick。 2nextTick() 这里代码不多主要逻辑就是 把传入的回调函数放进回调队列 callbacks。执行保存的异步任务 timeFunc就会遍历 callbacks 执行相应的回调函数了。 export function nextTick(cb?: (...args: any[]) any, ctx?: object) {let _resolve// 把回调函数放入回调队列callbacks.push(() {if (cb) {try {cb.call(ctx)} catch (e: any) {handleError(e, ctx, nextTick)}} else if (_resolve) {_resolve(ctx)}})if (!pending) {// 如果异步开关是开的就关上表示正在执行回调函数然后执行回调函数pending truetimerFunc()}// 如果没有提供回调并且支持 Promise就返回一个 Promiseif (!cb typeof Promise ! undefined) {return new Promise(resolve {_resolve resolve})} }可以看到最后有返回一个 Promise 是可以让我们在不传参的时候用的如下 this.$nextTick().then((){ ... })五、补充 在 vue 生命周期中如果在 created() 钩子进行 DOM 操作也一定要放在 nextTick() 的回调函数中。因为在 created() 钩子函数中页面的 DOM 还 未渲染这时候也没办法操作 DOM所以此时如果想要操作 DOM必须将操作的代码放在 nextTick() 的回调函数中 本文到此也就结束了希望对大家有所帮助。
http://wiki.neutronadmin.com/news/62716/

相关文章:

  • 网站建设的公司推荐怎样建立销售网站
  • 泰安网站建设哪里找百度seo搜搜
  • 建立网站 多少钱家居网站建设定位分析论文
  • 网站怎么优化关键词快速提升排名配置无法运行wordpress
  • 广西房地产网站建设满山红网站建设
  • 做企业网站还有钱挣吗拍摄形象宣传片
  • 权威的营销单页网站中国建设工程信息网官网建造师查询
  • 高职示范校建设网站No餐饮网站建设
  • 卡盟怎么网站怎么做wordpress评论
  • 钓鱼网站二维码制作软件最近高清中文在线国语字幕
  • 山东建站管理系统济南网站建设山东聚搜网咨询
  • 搭建一个网站的服务器帝国cms跟WordPress
  • 阿里云上可以做网站吗ui网页设计教程ppt
  • 免费可商用素材网站南京网站制作公司南京微尚
  • 抓取网站访客数据原理培训页面设计师
  • 电子商务网站开发的视频威海高区建设局官方网站
  • 做网站需要了解的内容廊坊seo优化排名
  • 品牌网站建设策clef wordpress
  • 网站建设优化服务流程移动端seo
  • 企业网站做的比较好有名的网站建设公司
  • 云核wordpress深圳网站优化团队
  • 合肥网站建设 卫来网络建设工程资质证书二维码扫描网站
  • 注册公司网上申请入口网站中国在建工程信息网
  • 免费网站后台管理模板下载今天的新闻头条最新消息
  • 做网站是用ps还是ai网络营销模式有哪几种
  • 网站百度关键词排名软件横峰县城乡建设网站
  • 网站开发费属于软件费吗建筑材料价格查询网站
  • 京东网站建设的特点网站设计分析怎么写
  • 软件开发培训机构找极客时间杭州优化网站
  • 产品推广运营的公司seo关键词排名优化要多少钱