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等均可 ...
随机推荐
- 前端:Uncaught TypeError: Cannot set property 'value' of null;
1.在写JS代码中的绑定事件时(将JS与HTML标签分开时),发现会有如下错误提示: Uncaught TypeError: Cannot set property 'onclick' of null ...
- Windows10 下 Neo4j1.5.8 安装教程
前言 Neo4j 是一个高性能的.NOSQL 图形数据库,它将结构化数据存储在网络上而不是表中.基于磁盘的.具备完全的事务特性的 Java 持久化引擎,这里就不把他和常用关系型数据库做对比了.因为篇幅 ...
- Variable 'xxxx' is accessed from within inner class, needs to be final or effectively final-Lambda 表达式的变量与作用域
问题的原因 问题代码: public static void main(String[] args) { Integer sum = 0; Integer count = 0; List<Int ...
- iptables简要介绍及使用iptables实践NAT技术
简介 iptables的文章多如牛毛,但是,我读了一些,发现虽然成体系,但是不便理解,今天就结合自己的理解,好好讲解下,另外,我们也会使用iptables来实验一个nat地址转换的demo,nat转换 ...
- 长连接:chatgpt流式响应背后的逻辑
一.前言: 提起长连接,我们并不陌生,最常见的长连接非websocket莫属了.即使没有在项目中实际用过,至少也应该有所接触.长连接指在一次网络通信中,客户端与服务器之间建立一条持久的连接,可以在多次 ...
- 2021-10-08 Core的LaunchSettings文件说明
{ "iisSettings": { //是否以IIS Express启动 "windowsAuthentication": false, //是否启用wind ...
- GitLab 无仓库 中了勒索病毒
坑爹的记录一下,并没有解决 Gitlab 昨天(2021-11-29)打开之后看不到项目了,下面这个吊样子 最后发现中病毒了,一堆的这个吊毛文件,复制一个打开看了一下 你别说这个黑客网页写的还不错,这 ...
- React报错:You are running `create-react-app` 5.0.0, which is behind the latest release (5.0.1).
错误 解决方案 说白了就是版本过低,升级下就好.或者按照提示卸载掉原来的版本,之后输入临时创建命令即可,如下图所示 参考链接 https://stackoverflow.com/questions/7 ...
- TypeScript: Object is of type 'unknown'.
错误代码展示 解决方案 将e声明为any类型,如下所示: // 修改蛇的X和Y值 try { this.snake.X = X; this.snake.Y = Y; }catch(e:any){ // ...
- 创建python虚拟环境并打包python文件
前言 当需要为一个离线环境部署python应用时,离线环境可能缺少各种python环境,有docker的话可以用docker,没有docker可以用pyinstaller打包成二进制文件.pyinst ...