Vue源码学习(十三):nextTick()方法
好家伙,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()方法的更多相关文章
- Vue源码学习1——Vue构造函数
Vue源码学习1--Vue构造函数 这是我第一次正式阅读大型框架源码,刚开始的时候完全不知道该如何入手.Vue源码clone下来之后这么多文件夹,Vue的这么多方法和概念都在哪,完全没有头绪.现在也只 ...
- Vue源码学习三 ———— Vue构造函数包装
Vue源码学习二 是对Vue的原型对象的包装,最后从Vue的出生文件导出了 Vue这个构造函数 来到 src/core/index.js 代码是: import Vue from './instanc ...
- Vue源码学习二 ———— Vue原型对象包装
Vue原型对象的包装 在Vue官网直接通过 script 标签导入的 Vue包是 umd模块的形式.在使用前都通过 new Vue({}).记录一下 Vue构造函数的包装. 在 src/core/in ...
- Vue 源码学习(1)
概述 我在闲暇时间学习了一下 Vue 的源码,有一些心得,现在把它们分享给大家. 这个分享只是 Vue源码系列 的第一篇,主要讲述了如下内容: 寻找入口文件 在打包的过程中 Vue 发生了什么变化 在 ...
- 【Vue源码学习】依赖收集
前面我们学习了vue的响应式原理,我们知道了vue2底层是通过Object.defineProperty来实现数据响应式的,但是单有这个还不够,我们在data中定义的数据可能没有用于模版渲染,修改这些 ...
- Vue源码解析之nextTick
Vue源码解析之nextTick 前言 nextTick是Vue的一个核心功能,在Vue内部实现中也经常用到nextTick.但是,很多新手不理解nextTick的原理,甚至不清楚nextTick的作 ...
- 最新 Vue 源码学习笔记
最新 Vue 源码学习笔记 v2.x.x & v3.x.x 框架架构 核心算法 设计模式 编码风格 项目结构 为什么出现 解决了什么问题 有哪些应用场景 v2.x.x & v3.x.x ...
- 【Vue源码学习】响应式原理探秘
最近准备开启Vue的源码学习,并且每一个Vue的重要知识点都会记录下来.我们知道Vue的核心理念是数据驱动视图,所有操作都只需要在数据层做处理,不必关心视图层的操作.这里先来学习Vue的响应式原理,V ...
- VUE 源码学习01 源码入口
VUE[version:2.4.1] Vue项目做了不少,最近在学习设计模式与Vue源码,记录一下自己的脚印!共勉!注:此处源码学习方式为先了解其大模块,从宏观再去到微观学习,以免一开始就研究细节然后 ...
- Vue源码学习(一):调试环境搭建
最近开始学习Vue源码,第一步就是要把调试环境搭好,这个过程遇到小坑着实费了点功夫,在这里记下来 一.调试环境搭建过程 1.安装node.js,具体不展开 2.下载vue项目源码,git或svn等均可 ...
随机推荐
- Java在算法竞赛中的一些技巧
转载请注明出处(- ̄▽ ̄)- 谈到算法竞赛中使用Java,那么有一个绕不开的点就是如何快速地输入输出.通常来说,Scanner类固然可以帮助我们顺利地完成各种输入要求,而syso(System.o ...
- 力扣 662 https://leetcode.cn/problems/maximum-width-of-binary-tree/
需要了解树的顺序存储 如果是普通的二叉树 ,底层是用链表去连接的 如果是满二叉树,底层用的是数组去放的,而数组放的时候 会有索引对应 当前父节点是索引i,下一个左右节点就是2i,2i+1 利用满二叉树 ...
- 即构SDK9月迭代:外部采集、音频频谱、房间附加消息等多个模块功能上新
即构SDK9月迭代来了,本月SDK在外部采集.音频频谱.房间附加消息等多个功能模块均有新功能上线,并且还针对K歌音乐场景下,优化了变调功能效果.以下是详细的迭代内容: LiveRoom 新增 1. ...
- 【阅读笔记】超分之LANR-NLM算法
论文信息 [Single Image Super-Resolution via Locally Regularized Anchored Neighborhood Regression and Non ...
- Python 运行 shell 命令的一些方法
哈喽大家好,我是咸鱼 我们知道,python 在自动化领域中被广泛应用,可以很好地自动化处理一些任务 就比如编写 Python 脚本自动化执行重复性的任务,如文件处理.数据处理.系统管理等需要运行其他 ...
- 2021-3-29 Enter按下事件
先在构造器中添加keydown事件 tBoxPsw.KeyDown += TBoxPsw_KeyDown; 在事件中添加按下enter按钮所触发的方法 private void TBoxPsw_Key ...
- python 打包模块:nuitka
该模块可以将python编译成C++级的可执行文件,是解决python图形化界面启动慢的神器. 1.环境配置 配置c/c++编译器:MinGW64 ,最低使用8.1版本,该资源自行下载. 百度网盘链接 ...
- 暑假刷题记 B
动态规划 字符串 杂题 A:Animals and Puzzle B:Vanya and Treasure 根号分治. 实际上是从 \((1, 1)\) 先找一个 \(1\),再找一个 \(2\dot ...
- 代码随想录算法训练营第八天| LeetCode 344.反转字符串 541. 反转字符串II 151.翻转字符串里的单词
344.反转字符串 卡哥建议: 本题是字符串基础题目,就是考察 reverse 函数的实现,同时也明确一下 平时刷题什么时候用 库函数,什么时候 不用库函数 题目链接/文章讲解/视频讲解:https: ...
- 洛谷 P1387 最大正方形 题解
方法1 二分+暴力+前缀和Check 注意细节 通过二维前缀和判定矩形内是否全为1,计算和等于长度的平方就判断为是 复杂度\(\Theta (n^2\log{n})\) #include <bi ...