2020-03-31-vue源码学习

1.为什么在vue中访问this.message而不是访问的this.data.message?
会在初始化的时候把data里放到vm._data 在访问vm.message的时候就使用proxy代理到vm._data.mesage来访问 然后对属性进行observe响应式。 为什么要这样呢?后面回来回答
2、vue的render template 和el优先级是什么?
最终都会转成render函数来挂载,先判断手写的render 没有则看template,如果是el的则会把el的通过outerHTML转成template形式 最后编译成render函数进行挂载
3、Vnode是在生命周期的哪个阶段生成的?
从updateComponent看出来 是先在mounted之前 beforeMounted之后(mounted之后页面全部都出来了 都挂载好了怎么会没有生成Vnode呢)
4、为什么simpleNormalizeChildren()是把数组拉平呢?把空数组和children拉平有什么意义?无用功吗?
那是因为我还不了解concat数组的用法 我实战了一下 可以完成把数组拉平
5、在把render函数的Vnode函数中的children处理成一维数组不明白?有什么意义?
6、_update 里面是patch函数 是什么流程?
首先首次渲染传入要挂载的的真实dom,转换成oldvnode ,获取其中的父DOM, 然后创建一个一模一样的真实dom挂载到父级DOM上,过程是创建获取Vnode的children 然后去递归执行,先挂载子元素 到当前dom上 后挂载当前dom到父级dom上。最后删除原来的那个真实dom节点。
7、初始化props的步骤?
https://www.yuque.com/chenshier/chuyi/nn4hqu
接收到props后是要挂载到全局的 所以也像data那样设置需要给对props进行响应式,如果传进来的是普通值 则进行响应式 ,如果是引用类型,则对props响应式的时候 会多props值的属性进行响应式 但是在父组件的时候已经对其响应式了 所以判断存在ob属性则直接返回。shouldObserve则是判断需不需要进行observe 一般props传进来的里面的引用类型都是由父组件进行响应式了 所以一般设置成false
8、初始化data的步骤?
会给每个data属性绑定一个ob属性 为一个observer 然后会进行getter和setter属性的初始化,进入的时候会判断 如果是对象属性 会对每个对象属性进行响应式,包括其子元素,如果是数组,也会响应式,会遍历数组的每个元素,数组的元素中如果有不是基础类型的 也会进行响应式 ,如果是基础类型 则不会响应式。
9、Vue.js 中的依赖收集是怎么处理的?和闭包有什么关联吗?
依赖收集的get函数大概就是一个闭包,这是一个函数,在我render函数对属性进行访问的时候会执行这个函数,然后这个函数里面会用到局部变量dep来进行依赖的手机,相当于就是我们在外部通过get函数访问了defineReactive1函数里面的局部变量dep 在对data进行响应式的初始化的时候会对一个变量在observer里面实例一个dep放在_ob_属性下,然后在去执行defineReactive1的时候又会声明一个dep,这样来说一个变量就刽有两个dep。在声明的时候会通过var childOb = !shallow && observe(val)来对ob属性下的observer进行再依赖收集一次。(这里我不明白为什么同一个属性会加入两个dep到watcher里面)。然后如果变量是一个数组的话 会依次进行递归收集到watcher里面。
初始化整个过程:首先会initState过程中会给data和props等属性响应式。继续执行的时候新建一个渲染watcher的时候会执行渲染和挂载函数,这时候会执行_render函数。然后会执行相应的get函数 然后进行依赖收集。
10、watcher怎么工作?
在同一时刻只有一个全局watcher的执行的。就是渲染的时候再初始化某个组件的时候new Watcher的时候在执行传入的_update函数前会对之前的watcher推进栈里面 再去将全局的watcher变量换成子组件的渲染watcher。update之后会出栈 变回父组件的watcher 。最后会清除掉不用的依赖。 简单说就是在嵌套组件的时候是先父后子 再从子到父的组件执行回来。
11、派发更新?
data改变的时候触发set函数,,然后执行当前这个属性的dep.notify函数,然后这个dep下的subs里面有对应的watcher.。然后加入到watcher队列。再去执行下一个dep 触发setter 添加watcher 如果多个属于一个watcher 只会添加一次,如果判断里面有就不会添加了 最后所有的watcher添加结束之后 去执行这个队列 这个 队列如果是渲染watcher就会去执行getter函数就会执行_update去更新内容刷新页面 如果是user watcher 就会去执行程序员定义的callback函数!!(在set的时候我去获取了到了childOb不知道有啥用)
12、Vue.js 中的 $nextTick 的原理是什么?它主要经历了哪些变化?为什么?
https://segmentfault.com/a/1190000020499713?utm_source=tag-newest
是把回调函数添加到一个callback数组中,等到下一个tick去执行,实现方法层层递进,最简单的降级到settimeout去执行这个回调函数 ,来达到下一个tick去执行的目的。

例子

这样的话我实际上打印出来的是
image.png

但是我看视频中不是的。
我调试出来是callback函数的添加顺序是从上到下按顺序执行的 但是执行到上面的resolve没有马上执行promise.then二十直接执行下一个callback ,后来再转回来执行的promise.then里面的(不知道为啥,可能是promise的关系吧)
但是如果在上面的nextTick不是promise.then而是直接的回调函数 则是添加callback的时候就直接执行了 而不是等到后执行。
13、源码中的dep.depend和childOb.dep.depend有什么区别?为什么要调用两次?为什么在observer里面定义一个dep在响应式里面又要定义一个dep?
https://segmentfault.com/q/1010000010977528
看了这篇文章还是不是太理解 ,由于本人太蠢。。。
因为在初始化的时候会给data里面的额每个属性都响应式,包括对象里面的属性。但是在给数组或者数组添加新元素的时候以及删除的时候,是监测不到set的,所以这个时候比如我需要给this.mess里面添加新属性的时候,这时候this.mess属性下的的observe则可以去触发this.mess属性的watcher 然后修改界面。而不是通过set函数里面。虽然在添加之后会对该属性响应式 但是如果不通过this.mess去通知修改,界面则不会修改。
例子

14.计算属性的实现原理?
初始化计算属性的时候会初始化一个计算watcher,传入的函数就是用户定义的computed自定义函数,然后把对应的属性添加到vm上,(但是如果是组件的话,组件在开始的时候会把计算属性添加到vm上。)然后执行defineComputed函数 设置访问此计算属性的get函数 没有设置set函数,(我遇到过这个错误,这个时候需要自己设置一个set函数)然后初始化阶段结束。之后就是访问render函数会对该属性访问,然后执行回调函数。执行的时候会执行这个watcher函数。然后执行watcher的回调函数然后执行用户的函数。然后访问依赖的属性,然后计算属性watcher会订阅依赖属性的变化。之后计算求值结束。 渲染watcher会订阅当前computed watcher。所以当计算属性依赖的属性更新的时候会通知computed watcher 变化 。然后计算watcher会通知渲染watcher更新界面变化。(会判断新值和旧值是否相等,如果相等则不会重新渲染)
https://segmentfault.com/a/1190000015826130
15、响应式原理图?
原理图

16.Vue.js 中的模板解析需要经历哪几个阶段?
三个阶段:
1、转化省AST,抽象语法树 parse
2、标记静态节点 optimize
3、转化成render函数 generate
https://www.jianshu.com/p/1c321032c83e
https://segmentfault.com/a/1190000012922342

17、vue-loader的特性?
https://www.jianshu.com/p/24cdd125ca4e

18、单元测试
从来没有接触过,看了阮一峰的mocha ,了解了一下吧 先放在这
http://www.ruanyifeng.com/blog/2015/12/a-mocha-tutorial-of-examples.html

你可能感兴趣的:(2020-03-31-vue源码学习)