1. nextTick
- 在下次 dom 更新循环结束之后执⾏延迟回调,可⽤于获取更新后的 dom 状态
- 新版本中默认是 mincrotasks , v-on 中会使⽤ macrotasks
- macrotasks 任务的实现:
- setImmediate / MessageChannel / setTimeout
2. ⽣命周期
init
- initLifecycle/Event ,往vm上挂载各种属性
- callHook: beforeCreated : 实例刚创建
- initInjection/initState : 初始化注⼊和 data 响应性
- created: 创建完成,属性已经绑定, 但还未⽣成真实 dom`
- 进⾏元素的挂载:
e
l
/
v
m
.
el / vm.
el/vm.mount()
- 是否有 template : 解析成 render function
- *.vue ⽂件: vue-loader 会将 编译成 render function
- beforeMount : 模板编译/挂载之前
- 执⾏ render function ,⽣成真实的 dom ,并替换到 dom tree 中
- mounted : 组件已挂载
update
- 执⾏ diff 算法,⽐对改变是否需要触发 UI 更新
- flushScheduleQueue
- watcher.before : 触发 beforeUpdate 钩⼦ - watcher.run() : 执⾏ watcher 中的notify ,通知所有依赖项更新UI
- 触发 updated 钩⼦: 组件已更新
- actived / deactivated(keep-alive) : 不销毁,缓存,组件激活与失活
- destroy
- beforeDestroy : 销毁开始
- 销毁⾃身且递归销毁⼦组件以及事件监听
- remove() : 删除节点
- watcher.teardown() : 清空依赖
- vm.$off() : 解绑监听
- destroyed : 完成后触发钩⼦
- 上⾯是vue的声明周期的简单梳理,接下来我们直接以代码的形式来完成vue的初始化
new Vue({})
function _init() {
initLifeCycle(vm)
initEvent(vm)
initRender(vm)
callHook(vm, 'beforeCreate')
initInjection(vm)
initState(vm)
initProvide(vm)
callHook(vm, 'created')
if (vm.$options.el) {
vm.$mount(vm.$options.el)
}
}
function mountComponent(vm) {
if (!this.options.render) {
let { render } = compileToFunctions()
this.options.render = render
}
callHook('beforeMounte')
vdom = vm.render()
vm._update(vdom)
callHook(vm, 'mounted')
}
funtion queueWatcher(watcher) {
nextTick(flushScheduleQueue)
}
function flushScheduleQueue() {
for(){
watcher.before()
watcher.update()
callHook('updated')
}
}
Vue.prototype.$destory = function() {
callHook(vm, 'beforeDestory')
remove()
watcher.teardown()
vm.$off()
callHook(vm, 'destoryed')
}
3. Proxy 相⽐于 defineProperty 的优势
let data = { a: 1 }
let reactiveData = new Proxy(data, {
get: function(target, name){
},
})
4. vue-router
mode
跳转
* this.$router.push()
* <router-link to=""></router-link>
占位
<router-view></router-view>
5. vuex
- state : 状态中⼼
- mutations : 更改状态
- actions : 异步更改状态
- getters : 获取状态
- modules : 将 state 分成多个 modules ,便于管理