VUE2.x
2020-10-29 22:11:21 3 举报
AI智能生成
vue思维导图
作者其他创作
大纲/内容
initProps
initMethods
proxy
defineProperty
对数据做响应式
get
set
defineReactive
walk
observeArray
observer
对data对象类型数据以及新添加的对象类型数据进行观测
initData
initComputed
initWatch
initState
parseHTML
generate
compileToFunctions
得到render(或_render)函数
调用render方法生成vdom
updateProperties
createElm
createTextNode
patch
调用vm._update产生真实dom
new Watcher
将数据结合dom渲染到页面上
mountComponent
vm.$mount
initMixin
混入update方法
混入mountComponent方法
lifecycleMixin
mergeOptions
mergeHook
混入生命周期
callHook
mixin
globalApi
混入render方法
renderMixin
this._init
Vue初渲染
对象类型
数组类型
数据响应式
分支主题
先初始化数据
将模板编译
生成虚拟节点
生成真实的dom
挂载页面上
dep(小管家)
watcher
dep(大管家)
get将dep与watcher相互建立关系
new Observer类
页面重新更新渲染
自由主题
render 函数
对响应式数据操作
vue的数据更新流程
nextTick更新原理
queueWatcher
nextTick
手动调用vm.$nextTick(cb)
watch监控原理
watch属性
createWatcher
new Watcher生成一个用户watcher
watcher身上的user标识
执行watch上定义的方法
oldVnode.el.parentNode.replaceChild
不一样时,直接将新vdom生成真实dom替换老的vdom
一样时,继续往下比对
1.比较老vdom最外层标签与新vdom的最外层标签
oldVnode.el.textContent = vnode.text
是文本节点,直接将新的vdom上文本替换掉老的dom文本
不是,继续往下比对
2.比较是文本节点
1.比较新老vdom上的属性并做更新页面dom
el.innerHTML = ''
1.当老的vdom上有子节点,而新vdom没有,直接将老dom上节点置空
el.appendChild(createElm(child))
2.当老的vdom上没有子节点,而新的vdom子节点,直接将新vdom上的子节点生成真实dom追加到老dom树上
孩子间节点比较
移动指针,老与新的开头指针都+1
相等
不相等,继续往下对比
1.比较old头<--->new头
移动指针,老与新的结尾指针都-1
2.比较old尾<--->new尾
移动指针,老的开头指针+1,新的结尾指针-1
3.比较old头<--->new尾
移动指针,老的结尾指针-1,新的开头指针+1
4.比较old尾<---->new头
1.如果老的没有,而新的有,则将新vdom的节点创建为真实节点,在将其追加到老的开头指针指向元素的前面
将新vdom上的孩子与老vdom的孩子一一比对
新的开头指针+1,老的不动
5.暴力对比
循环比较新老vdom里的元素
循环比较
定义新老vdom子节点的指针与指针对应元素
做diff比较
3.当老vdom与新vdom都有子节点
2.比较元素里面的子节点
3.到了这时,那么说明标签一样,标签存在可复用的情况
传入了新vdom与老vdom进行比较
diff流程,diff都是将老新的vdom进行比较后,在去新老的差异更新到老dom上,能移动元素就不创建元素,只有是老的没有该元素复用才创建元素
new Watcher
dirty
defineComputed
computed实现
计算属性的本质也是一个watcher
computedWatcher执行getter(computed内部定义的方法),这个watcher被创建后要等到它定义的属性名被读取之后才会与内部依赖的data值进行关联,关联之后,我们的watcher栈中还有渲染watcher时,那么我们就会将这个watcher放到Dep.traget上,然后我们可以通过dep与watcher是n对n的关系,通过这个计算属性watcher去找他收集起来的dep,将渲染watcher添加到这些dep身上。
组件创建挂载流程
当页面第一次渲染时
Vue.extend()
在data.hook上添加init方法,这个init方法是用于创建组件实例的
createComponent
得到<my-button></my-button>的vdom
页面第一次render函数执行结束
执行页面第一次渲染的patch
通过 createComponent 判断是否是组件的节点
createElm生成父节点,并递归创建真实的子节点元素
以<my-button></my-button>为例
vuex源码分析
获取module实例下的_children对应的属性
getChild
给module实例下的_children添加子实例
addChild
将模块定义好的mutations方法添加到实例下的 this._raw.mutations
forEachMutation
将模块定义好的actions方法添加到实例下的 this._raw.actions
forEachAction
将模块定义好的getters方法添加到实例下的 this._raw.getters
forEachGetter
将Module实例下的_children属性进行遍历
forEachChild
Module类
这里的注册都是往全局store的对应的属性去添加的,如果某个模块配置了命名空间,那么会在添加的属性的时候,添加模块前缀
有无namespace对模块的state、mutations、actions、getters的影响
得到模块的命名
getNamespaced
ModuleCollection
installModule
resetStoreVM
主要靠的是
vuex可以使用插件,例如内置的logger日志插件和持久化插件
plugin
Store类
vuex
vue-router源码分析
使用Vue.mixin()上混入beforeEach方法
最简单的就是渲染一个<a></a>标签
link.js
这里需要根据递归来获取到渲染对应路由组件
view.js
注册全局组件`router-link`与`router-view`
在Vue原型上定义$route与$router属性
执行install方法
得到pathMap
createMatcher
通过super调用父类创建出(createRoute)默认的路由对象current
hash实例对象
history实例对象
得知使用路由的类型(hash或history),并创建对应的实例
new VueRouter
全局混入了_routerRoot属性并且所有组件都能通过它访问到router实例
更新current为当前路由信息
给window绑定好hash的监听函数【hashchange事件】,(只有初始化是绑定,之后切换并不需要重新绑定)
调用transitionTo跳转到当前的路由,调用match方法得到当前访问路径并匹配出需要渲染的路由表
初始化结束
执行VueRouter类上的init方法
根实例被创建时执行全局混入的beforeEach方法
挂载到根实例上
Vue.use
store.js
当使用router-link组件进行路由切换或者是调用this.$router.push()
vue-ssr原理分析
client.bundle.js
client-entry
server.bundle.js
server-entry
app.js
前端打包的js包,用于客户端激活
传入template,页面渲染模板
传入后端打包的boundle
使用vue-server-renderer包创建一个渲染器---> render
调用render.renderToString({ url: ctx.url })进行渲染,返回给前端
后端处理 koa服务
vue-router
在initState就被创建出来了,但由于是lazy的特点,它不会默认执行回调函数,即不会立马建立watcher与依赖的数据之间的关系,直到我们去读取computed定义额属性时,触发evaluate方法,之后在去触发getter的方法,由于getter的方法有data上值,调用getter就相当于取了data上的值,那么这个watcher就会被这个值的dep收集起来
computed-watcher(computed方法)
在initState就被创建了,如果传入了 immediate 属性,那么会立马执行回调函数,若未传,则是把这个watcher推入到watcher栈中
user-watcher(watch方法)
在组件挂载时,创建出来的,之后立马入watcher栈中,为了在执行页面更新函数时,读取页面的值时,让这些值的dep去收集这个watcher
渲染watcher
三种watcher的创建以及何时收集依赖
watcher的执行顺序一定是 computed watcher -> use watcher -> render watcher
为了将动态添加的模块的父子关系确定好
这里将动态模块拿去注册,并在里面找到动态模块的父子关系
vuex内部重新注册的话 会重新生成实例, 虽然重新安装了 ,只解决了状态的问题,但是computed就丢失了
注册新模块
VUE2.x
0 条评论
回复 删除
下一页