好家伙,nextTick,

(...这玩意,不太常用)

1.什么是nextTick

在Vue中,nextTick是一个用于异步执行回调函数的方法。

它在Vue更新DOM后被调用,以确保在下一次DOM更新渲染完成后执行回调函数。

而事实上,我们把队列处理的操作封装到了nexrTick方法中.

实际上,Vue在更新DOM时是异步执行的。

当你修改Vue实例的数据时,Vue会对依赖这些数据的虚拟DOM进行重新渲染,然后更新到真实的DOM上。

但是,DOM更新是在下一个事件循环中执行的,而不是立即执行。

所以,如果你想在DOM更新后执行一些操作,你就可以使用nextTick方法。

这个方法会将回调函数推入到微任务队列中,并在DOM更新后执行。

这样可以确保你在操作更新后的DOM,比如获取元素的宽高等,而不是得到修改前的值。

举一个非常简单的例子

Vue.Mixin({ //全局
created: function b() {
// console.log('b----2')
}
})
let vm = new Vue({
el: '#app', //编译模板
// data: {
// },
data() {
// console.log(this)
return {
msg:'牛肉',
arr: [1, 2, 3],
}
},
created() {
// console.log(555)
}
})
console.log(vm.msg,"||直接打印msg的值")
setTimeout(() => {
//注意数据更新多次,vm._updata(vm._render()) 只需要执行一次
vm.arr.push({b:5})
vm.arr.push({b:6})
console.log(vm.msg,"||计时器打印msg的值")
vm.msg = '张三'
vm.$nextTick(()=>{
console.log(vm.msg,"||nextTick()方法打印msg的值")
})
}, 1000)

这里

可以看出来

nextTick()方法中的console确实拿到了最新的值

2.代码实现

给vm原型添加$nextTick方法

2.1.initState.js

export function stateMixin(vm) {
//列队批处理
//1.处理vue自己的nextTick
//2.用户自己的
vm.prototype.$nextTick = function (cb) {
// console.log(cb)
nextTick(cb)
}
}

2.2.watcher.js

(此处为部分代码)

let queue = [] // 将需要批量更新的watcher 存放到一个列队中
let has = {}
let pending = false
//数组重置
function flushWatcher() {
queue.forEach(item => {
item.run()})
queue = []
has = {}
pending = false
}
function queueWatcher(watcher) {
let id = watcher.id // 每个组件都是同一个 watcher
// console.log(id) //去重
if (has[id] == null) {//去重
//列队处理
queue.push(watcher)//将wacher 添加到列队中
has[id] = true
//防抖 :用户触发多次,只触发一个 异步,同步
if (!pending) {
//异步:等待同步代码执行完毕之后,再执行
// setTimeout(()=>{
// queue.forEach(item=>item.run())
// queue = []
// has = {}
// pending = false
// },0)
nextTick(flushWatcher) // nextTick相当于定时器
}
pending = true
}
}

2.3.nextTicks.js

let callback = []
let pending = false
function flush(){
callback.forEach(cb =>cb())
pending =false
}
let timerFunc
//处理兼容问题 //判断全局对象中是否存在Promise
//看浏览器是否支持promise
if(Promise){
timerFunc = ()=>{
Promise.resolve().then(flush) //异步处理
}
}else if(MutationObserver){ //h5 异步方法 他可以监听 DOM 变化 ,监控完毕之后在来异步更新
let observe = new MutationObserver(flush)
let textNode = document.createTextNode(1) //创建文本
observe.observe(textNode,{characterData:true}) //观测文本的内容
timerFunc = ()=>{
textNode.textContent = 2
}
}else if(setImmediate){ //ie
timerFunc = ()=>{
setImmediate(flush)
}
}
export function nextTick(cb){
// 1vue 2
// console.log(cb)
//列队 [cb1,cb2]
//此处,注意,我们要处理用户的nextTick()也要处理vue自己的nextTick
callback.push(cb)
//Promise.then() vue3 if(!pending){
timerFunc() //这个方法就是异步方法 但是 处理兼容问题
pending = true
}
}

 

Vue源码学习(十三):nextTick()方法的更多相关文章

  1. Vue源码学习1——Vue构造函数

    Vue源码学习1--Vue构造函数 这是我第一次正式阅读大型框架源码,刚开始的时候完全不知道该如何入手.Vue源码clone下来之后这么多文件夹,Vue的这么多方法和概念都在哪,完全没有头绪.现在也只 ...

  2. Vue源码学习三 ———— Vue构造函数包装

    Vue源码学习二 是对Vue的原型对象的包装,最后从Vue的出生文件导出了 Vue这个构造函数 来到 src/core/index.js 代码是: import Vue from './instanc ...

  3. Vue源码学习二 ———— Vue原型对象包装

    Vue原型对象的包装 在Vue官网直接通过 script 标签导入的 Vue包是 umd模块的形式.在使用前都通过 new Vue({}).记录一下 Vue构造函数的包装. 在 src/core/in ...

  4. Vue 源码学习(1)

    概述 我在闲暇时间学习了一下 Vue 的源码,有一些心得,现在把它们分享给大家. 这个分享只是 Vue源码系列 的第一篇,主要讲述了如下内容: 寻找入口文件 在打包的过程中 Vue 发生了什么变化 在 ...

  5. 【Vue源码学习】依赖收集

    前面我们学习了vue的响应式原理,我们知道了vue2底层是通过Object.defineProperty来实现数据响应式的,但是单有这个还不够,我们在data中定义的数据可能没有用于模版渲染,修改这些 ...

  6. Vue源码解析之nextTick

    Vue源码解析之nextTick 前言 nextTick是Vue的一个核心功能,在Vue内部实现中也经常用到nextTick.但是,很多新手不理解nextTick的原理,甚至不清楚nextTick的作 ...

  7. 最新 Vue 源码学习笔记

    最新 Vue 源码学习笔记 v2.x.x & v3.x.x 框架架构 核心算法 设计模式 编码风格 项目结构 为什么出现 解决了什么问题 有哪些应用场景 v2.x.x & v3.x.x ...

  8. 【Vue源码学习】响应式原理探秘

    最近准备开启Vue的源码学习,并且每一个Vue的重要知识点都会记录下来.我们知道Vue的核心理念是数据驱动视图,所有操作都只需要在数据层做处理,不必关心视图层的操作.这里先来学习Vue的响应式原理,V ...

  9. VUE 源码学习01 源码入口

    VUE[version:2.4.1] Vue项目做了不少,最近在学习设计模式与Vue源码,记录一下自己的脚印!共勉!注:此处源码学习方式为先了解其大模块,从宏观再去到微观学习,以免一开始就研究细节然后 ...

  10. Vue源码学习(一):调试环境搭建

    最近开始学习Vue源码,第一步就是要把调试环境搭好,这个过程遇到小坑着实费了点功夫,在这里记下来 一.调试环境搭建过程 1.安装node.js,具体不展开 2.下载vue项目源码,git或svn等均可 ...

随机推荐

  1. 【Springboot】过滤器

    Springboot实现过滤器 实现过滤器方式有两种: Filter过滤器具体实现类 通过@WebFilter 注解来配置 1.Filter过滤器具体实现类 1.1 实现Filter @Compone ...

  2. 【Java】工具类 -- 持续更新

    Java原生工具类 Objects requireNotNull():为空抛异常,不为空返回本身 deepEquals():对象深度相等(数组层面)判断 调用Arrays.deepEquals0() ...

  3. ISP-长短曝光融合生成HDR图像

    1.高动态范围图像相关 图像的动态范围是指一幅图像中量化的最大亮度与最小噪声的比值.高动态范围HDR(high dynamic range)图像,能够完整表示真实场景中跨度很大的动态范围.采用普通CM ...

  4. 【转载】Linux虚拟化KVM-Qemu分析(七)之timer虚拟化

    原文信息 作者:LoyenWang 出处:https://www.cnblogs.com/LoyenWang/ 公众号:LoyenWang 版权:本文版权归作者和博客园共有 转载:欢迎转载,但未经作者 ...

  5. pgrep:根据名称或其他属性查找进程(查找系统中running状态的进程)

    用法示例 # 根据名称过滤 dewan Work ~/code/shell% pgrep qemu 3570191 dewan Work ~/code/shell% pgrep qemu -l 357 ...

  6. OceanBase 分布式存储管理

    分布式存储管理 分区表管理 定义 把普通的表的数据按照一定的规则划分到不同的区块内,同一区块的数据物理上存储在一起. 每个分区还能按照一定的规则再拆分成多个分区,这种分区表叫做二级分区表. 分区分类 ...

  7. Django CSRF cookie not set.

    错误原因 由于django框架的settings.py配置了中间件,为了防止跨站请求伪造,form表单POST方式会导致出现报错 解决办法: 将'django.middleware.csrf.Csrf ...

  8. 无linux基础也能熟练掌握git的基本操作

    git是一个用来管理项目的工具,它的远程仓库有github.gitee.gitlab代码托管中心,既可以用于个人共享代码,又可以用于团队进行项目的协作与发布,那么我们一起来了解一下git该如何使用~ ...

  9. BurpSuite设置上游代理访问内网

    转载原文 原理知道了后,开始! 拿到B的shell后,添加路由 拿到B的shell后,开启sock4 在D主机上设置好 最后成功抓到包

  10. centos7升级内核到最新稳定版

    前言 centos7默认的内核版本才3.10,诸如VXLAN.eBPF等特性无法体验,因此需要升级.目前(2022.02)Linux的内核版本已更新到5.16. 步骤 更新仓库 yum update ...