vue process.env获取不到_从文档开始,重学vue(下)源码级别

769fc93b1af1581bf13a45875ea68617.png

此篇文章主要是从应用及源码层面讲解vue部分常用api,阅读起来可能略有难度,新手可以看《从文档开始,重学vue(上)》

示例代码均在vue-cli3中完成

Vue.extend()

可以使用 extend 创建一个子类,该方法通常用于构建全局组件,如弹框组件等,下面我们就用它来制作个全局alert组件吧

  1. 首先我们需要一个alert.vue组件,组件很简单就接受一个参数,然后有两个控制显示隐藏的方法58907b6711c7acc75c27507b839b991b.png
  2. 需要把alert挂载到body 注意extend的使用方式bdacb91c3a4d0943b6d0c11176329728.png
  3. 使用

使用之前别忘了在main.jsuse一下

import Alert from "./components/Alert/create";Vue.use(Alert)

用起来也非常方便,如下:

mounted(){	this.$alert('公众号,码不停息')}

上面我们使用extend直接给他传了个组件进去,其实我们也可以给extend的配置对象,如下:

Vue.extend({ template: "{{msg}}", data() {   return {     msg: "码不停息"   }; }});

下面我们通过源码来看看在vue内部extend都做了哪些事情,关键性代码已经加上注释0fb0646812d4dbdbe4b2cdee89e56d34.png主要做的事情就是把通过extend挂载的组件初始化,并完善里面的options最后返回组件

Vue.nextTick()

如果想理解清楚nextTick,需要我们了解vue异步队列javascript(确切的说是浏览器)的事件循环机制

  • vue异步更新队列
  • 事件循环机制

可能你还没有注意到,Vue 在更新 DOM 时是异步执行的。只要侦听到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更。如果同一个 watcher 被多次触发,只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作是非常重要的。然后,在下一个的事件循环“tick”中,Vue 刷新队列并执行实际 (已去重的) 工作。Vue 在内部对异步队列尝试使用原生的 Promise.then、MutationObserver 和 setImmediate,如果执行环境不支持,则会采用 setTimeout(fn, 0) 代替(Vue官网)

可以简单的总结为Vue实现响应式并不是数据发生变化之后 DOM 立即变化,而是按一定的策略进行 DOM 的更新,他的策略就是同一事件循环中的所有数据变化完成之后,再统一进行视图更新,如果在这个过程中想要操作dom就比较棘手了,而Vue.nextTick就是来解决这样的问题,如下:

  
{{ time }}
export default { data() { return { time: "" }; }, methods: { getDom() { return document.getElementById("time").innerHTML; } }, mounted() { this.time = new Date().toLocaleTimeString(); console.log("获取time", this.getDom()); //获取不到 this.$nextTick(() => { console.log("获取time", this.getDom()); //可以获取到 }); }};
6b91a6dec1082b3924e8f06479354565.png

可以看到,当我们给time赋值后直接通过原生dom获取值是获取不到的,而用this.$nextTick(callback)就可以获取到了,那nextTick在内部做了什么呢?我们找到相应的源码68bf2e1088a6eb9cddc06446222d537e.png可以看出,当我们在代码中执行$nextTick方法时,内部是调用了nextTick,那我们再来看看nextTick方法里面都有什么?066a48ab184cd3d0151702b8fb0343cf.png原来nextTick方法把我们传的函数都push到了一个callback数组里,那这个数组是什么时候执行呢?为了方便看,我把相关代码都复制出来如下:f634f3d9c35b09d18d48703b716bd485.png代码较长,可以放大观看,关键代码已给出注释,主要逻辑如下:

用户调用$nextTick(callback) -> 把用户传入函数push到callback数组 -> 检测当前平台环境决定使用哪种方式处理异步 -> 执行flushCallbacks函数 -> flushCallbacks中循环执行callback

因为微任务会在当前宏任务执行完毕后立即执行,这样就能保证在执行$nextTick()的时候,当前宏任务(包括页面渲染)已经执行完毕

Vue.set()

Vue.set()设置的值是响应式,当我们需要对 复杂数据类型 新增属性和值,同时需要新增的值是 响应式 的时候就需要使用该api 如下所示:

  1. 直接给对象赋一个新的属性和新值
  
公众号: {{ userInfo.name }}
作者:{{ userInfo.author || "暂无数据" }}
export default { data() { return { userInfo: { name: "码不停息" } }; }, methods: {}, mounted() { this.userInfo.author = "刘小灰"; // 注意 userInfo开始没有author属性 }};

渲染结果如下, 数据没有出来,新增的author不是响应式72e9b6865d1bc340343cc2b8e67962d8.png

  1. 我们再用Vue.set()给对象赋一个新的属性和新值
  
公众号: {{ userInfo.name }}
作者:{{ userInfo.author || "暂无数据" }}
export default { data() { return { userInfo: { name: "码不停息" } }; }, methods: {}, mounted() { this.$set(this.userInfo, "author", "刘小灰"); //使用set赋值 }};

再看看结果,新增的author是响应式63871c1363c916fe203510106b838183.png

除了基本使用,我们来思考下Vue为什么要设置这个api,为什么直接通过.语法添加的属性就不是响应式的呢? 使用this.$set()是有如何做到响应式的呢?

我们来源码中找答案

简单了解下响应式

响应式的具体表现是当我们把data中的属性和页面绑定后,改变data中的数据后,页面会自动更新,那Vue是如何实现响应式的呢?

不难得出在vue2.x中是使用Object.defineProperty对数据进行劫持来实现响应式,当我们初始化的时候,会把每一个数据都进行依赖收集,内部主要是通过遍历及递归来实现,如下(关键代码已给出注释):2082a28efd71ed0d567440950f12c7f3.png下面我们来看看核心方法defineReactive都干了什么事情(关键代码已给出注释)288e695bfa4fce4632cc3886978d3520.png

大体流程

初始化 -> 执行Observer -> 如果是数组特殊处理,否则遍历子 -> 执行walk -> defineReactive进行响应式处理,如果数据中对象嵌套,递归之,否则进行依赖收集,确保全部数据都经过Object.defineProperty的洗礼 -> 响应式处理完毕

这时问题来了, 如果你在代码中给某个对象通过.语法新加个属性,这个时候初始化过程早已结束,新加的属性并没有经过Object.defineProperty的洗礼,自然不会变成响应式数据,这个时候我们就需要使用Vue.set()方法,让数据变成响应式,那set中是如何做的呢?其实就是重新调了下Object.definePropertyset方法进行依赖收集即可

关于Vue是如何对数组进行特殊处理的,可以看Object.defineProperty是如何实现对数组的监听

Vue.use()

安装 Vue 插件使用,use的源码比较短我们直接看源码:如下(关键代码已给出注释)984bed7df7e54bb100027e4be308c692.png所以在我们平常使用时,我们有两种使用方式

方式一:Vue.use({	install(vue){        }})方式二:Vue.use((vue)=>{})

无论是哪种方式,Vue都会把vue实例在回调中返回回来供我们使用

最后

最后我想说说为什么我们要学习源码,我觉得源码能不能学透并不重要(当然,如果你可以把源码彻底看懂也再好不过),对我们大部分人来说,学习源码最重要的目的是 查漏补缺 ,看大佬们是怎么写代码,是怎么组织代码,而这种能力不是我们多做几个项目,多发几个ajax请求能够得到的,就拿自己来说,看了源码后我发现自己对函数式编程,对发布订阅模式掌握的还不是不好,然后自己花些时间再加强下这方面的理解,然后把自己理解到的知识再在看源码中得以升华,我感觉这是最酷的!

最后的最后

交个朋友吧,关注微信公众号,拉你进群,和一群志同道合的人学习源码

5a87909b22a4c6f3ea6b4e2d62d37c52.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/446017.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Microsoft Visual Studio2019环境下搭建SDL开发环境

参考链接 《基于 FFmpeg SDL 的视频播放器的制作》课程的视频_雷霄骅的博客-CSDN博客_雷霄骅ffmpeg视频教程小学期课程资料 - 基于FFmpegSDL的视频播放器的制作.zip_免费高速下载|百度网盘-分享无限制辅助参考链接VS自动链接到Windows上随vcpkg安装的SDL2库 | 码农俱乐部 - G…

不关注公众号可以获取openid吗_微信公众号粉丝迁移

目录 [toc] 微信公众号迁移 正常的公众号迁移直接通过微信操作就可以,如下图。但是因为udb数据里面存的是迁移前公众号的openid以及unionid,需要自行获取新旧openid以及unionid。 旧的用户信息要在迁移之前获取,第三步点击同意之后就公众号的接口就调不通…

建筑专业规范大全 2020版_房屋建筑工程现行规范标准目录汇编(2020版)—建筑电气...

房屋建筑工程现行规范标准目录汇编(2020版)建筑电气规范编号规范名称GB 50034-2013建筑照明设计标准GB 50052-2009供配电系统设计规范GB 50053-201320kV及以下变电所设计规范GB 50057-2010建筑物防雷设计规范GB 50147-2010电气装置安装工程 高压电器施工及验收规范GB 50148-201…

基于Microsoft Visual Studio2019环境编写ffmpeg视频解码代码

旧代码 旧代码使用了很多过时的API,这些API使用后,vs会报编译器警告 (级别 3) C4996的错误即 函数被声明为已否决 报 C4996的错误 // test_ffmpeg.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #define SDL_MAIN_HANDLED …

16进制转double dotnet_终于把计算机进制弄明白了!

And theres one thing that I need from you我只需要你为我做一-件事Can you come through, through待在我的身边就好Through, yeah你可以抚慰一切不满And theres one thing that I need from you你可以过来Can you come through?待在我的身边吗-comethruJeremy Zucker进制进制…

FFmpeg源代码简单分析-架构图-解码

参考链接 FFmpeg源代码结构图 - 解码_雷霄骅的博客-CSDN博客_ffmpeg雷霄骅函数背景色 函数在图中以方框的形式表现出来。不同的背景色标志了该函数不同的作用: 粉红色背景函数:FFmpeg的API函数。白色背景的函数:FFmpeg的内部函数。黄色背景…

JUnit单元测试笔记

#01 JUnit简介 1.在项目工程中的Library,add 一个JUnit的Jar包,按需要添加JUnit 3 或 JUnit 4(分为被测试类与测试类较佳)。 2.单元测试是由程序员完成的。 3.Java 5 之前的版本只能 用JUnit 4前的版本(因为JUnit 4用到Java 5的…

jqery获取每个月天数_三年级《年、月、日》单元重要知识点整理汇总,以及难点题型解析...

昨天给大家分享了《计算经过的时间》问题,今天给大家分享的是《年、月、日》单元中重要的几个知识点,以及难点题型解析。知识点1 感知年、月、日一、结合生活实际,看看下面事情需要经过多少时间。跑完100米大约需要经过十几(秒)。2.打一场篮球…

FFmpeg源代码简单分析-架构图-编码

参考链接 FFmpeg源代码结构图 - 编码_雷霄骅的博客-CSDN博客_ffmpeg 源码函数背景色 函数在图中以方框的形式表现出来。不同的背景色标志了该函数不同的作用: 粉红色背景函数:FFmpeg的API函数。白色背景的函数:FFmpeg的内部函数。黄色背景的…

为革命,保护视力——为Eclipse更换暗黑皮肤及编辑页面的字体颜色主题

1.在Eclipse中的菜单栏的Help -> Eclipse Market 的 Search栏中输入 Eclipse Moonrise UI Theme ,之后自己执生啦(确保上网配置正确)。 2.与上面操作类似,输入 Eclipse Color Theme,选择安装。 3.选择菜单栏的Win…

python函数可以作为容器对象吗_正确理解Python函数是第一类对象

正确理解 Python函数,能够帮助我们更好地理解 Python 装饰器、匿名函数(lambda)、函数式编程等高阶技术。函数(Function)作为程序语言中不可或缺的一部分,太稀松平常了。但函数作为第一类对象(First-Class Object)却是 Python 函数的一大特性。那到底什么…

FFmpeg源代码简单分析-通用- av_register_all()

参考链接 ffmpeg 源代码简单分析 : av_register_all()_雷霄骅的博客-CSDN博客_av_register_all()从学龄前开始解读FFMPEG代码 之 avcodec_register_all函数_zzyincsdn的博客-CSDN博客

@suppressWarnings(unchecked)及其相关属性在Java中意思

首先suppressWarnings("unchecked")是JDK1.5中新加入的Annotation语法,用来压制警告信息的。 编写代码时,有时会提示一些警告(例如:使用已经废弃的类,没有加入泛型等),如果不想让程序…

FFmpeg源代码简单分析-通用-avcodec_register_all()

参考链接 ffmpeg 源代码简单分析 : avcodec_register_all()_雷霄骅的博客-CSDN博客

pythonsklearn乳腺癌数据集_Python的Sklearn库中的数据集

一、Sklearn介绍scikit-learn是Python语言开发的机器学习库,一般简称为sklearn,目前算是通用机器学习算法库中实现得比较完善的库了。其完善之处不仅在于实现的算法多,还包括大量详尽的文档和示例。其文档写得通俗易懂,完全可以当…

FFmpeg源代码简单分析-通用- 内存的分配和释放(av_malloc()、av_free()等)

参考链接 FFmpeg源代码简单分析:内存的分配和释放(av_malloc()、av_free()等)_雷霄骅的博客-CSDN博客_av_malloc 内容介绍 内存操作的常见函数位于libavutil\mem.c中本文记录最常使用的几个函数: av_malloc()av_realloc()av_mal…

面试题——死锁的实现

public class DeadLock {public static Object Chopstick_1 new Object();public static Object Chopstick_2 new Object();public static void main(String[] args) {final DeadLock deadLock new DeadLock();// 第一个线程 new Thread(new Runnable() {public void run()…

python回归分析实验_python线性回归实验

实验算法python线性回归实验【实验名称】Python线性回归实验【实验要求】掌握Python线性回归模型应用过程,根据模型要求进行数据预处理,建模,评价与应用;【背景描述】线性回归是利用数理统计中回归分析,来确定两种或两…

FFmpeg源代码简单分析-通用-结构体分析-AVFormatContext

参考链接 FFMPEG结构体分析:AVFormatContext_雷霄骅的博客-CSDN博客_avformatcontext AVFormatContext AVFormatContext是包含码流参数较多的结构体结构体的定义位于libavformat/avformat.h/*** Format I/O context.//格式化 I/O 上下文* New fields can be added…

log4j详解与实战

log4j详解与实战 http://www.iteye.com/topic/378077