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…

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

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

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

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

plsql如何显示表结构图_【论文攻略】排版技巧——如何用 Word 编辑参考文献

每个需要写毕业论文的朋友都会发现,修改文献是一件非常痛苦的事情,虽然现在也有很多软件可以编排参考文献,其实 word 本身就可以。采用合适的编辑方法会方便地做到整齐,规范, 自动排序和交叉引用。 1. 以尾注的方式插入第一个参考文献将光标定…

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

参考链接 FFMPEG结构体分析:AVCodecContext_雷霄骅的博客-CSDN博客_avcodeccontext AVCodecContext AVCodecContext是包含变量较多的结构体(感觉差不多是变量最多的结构体)结构体的定义位于avcodec.h关键的变量如下所示(仅仅考虑…

Hello OpenGL——OpenGL在Visual c++6.0安装和配置

1、下载并安装glut库opengl的glut库 GLUT不是OpenGL所必须的,但它会给我们的学习带来一定的方便,推荐安装。 Windows环境下的GLUT下载地址:(大小约为150k) http://www.opengl.org/resources/libraries/glut/glutdlls37…

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

参考链接 FFMPEG结构体分析:AVIOContext_雷霄骅的博客-CSDN博客_aviocontext AVIOContext AVIOContext是FFMPEG管理输入输出数据的结构体结构体的定义位于位于avio.h关键的变量如下所示 unsigned char *buffer:缓存开始位置int buffer_size&#xff1…

初闻动态规划

前言 本文以一道常见的算法面试题开篇,引入动态规划的基础概念, 介绍其思考过程。 正文 一、常见的一道算法面试题——上台阶 有一个楼梯总共n个台阶,只能往上走,每次只能上1个、2个台阶,总共有多少种走法。 解决…

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

参考链接 FFMPEG结构体分析:AVCodec_雷霄骅的博客-CSDN博客_avcodec AVCodec AVCodec是存储编解码器信息的结构体结构体的定义位于avcodec.h文件中最主要的几个变量 const char *name:编解码器的名字,比较短const char *long_name&#xff…

SLF4J简介与使用(整合log4j)

SLF4J简介与使用(整合log4j) 一、概念 SLF4J的全称是Simple Logging Facade for Java,即简单日志门面。SLF4J并不是具体的日志框架,而是作为一个简单门面服务于各类日志框架,如java.util.logging, logback和log4j。 SLF4J提供了统一的记录…

multism中ui和uo应该怎么表示_王者荣耀:梦泪直播时谈到体验服大改动,表示装备的改动很关键...

王者荣耀的主播梦泪,大家都很熟了,也是一个很强的主播,他对于王者荣耀的理解,还是非常深刻的,而最近王者荣耀的体验服,进行了大改动,也是改变了很多的东西。对此,网友们也是非常的在…