1. nextTick
在下次 dom 更新循环结束之后执⾏延迟回调,可⽤于获取更新后的 dom 状态
新版本中默认是 mincrotasks , v-on 中会使⽤
macrotasks macrotasks 任务的实现:
setImmediate / MessageChannel / setTimeout
2. ⽣命周期
init
initLifecycle/Event ,往vm上挂载各种属性
callHook: beforeCreated : 实例刚创建
initInjection/initState : 初始化注⼊和 data 响应性
created: 创建完成,属性已经绑定, 但还未⽣成真实 dom`
进⾏元素的挂载: $el / vm.$mount()
是否有 template : 解析成 render function
*.vue ⽂ 件 : vue-loader 会 将 <template> 编 译 成 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({}) // 初始化Vue实例 function _init() { // 挂载属性 initLifeCycle(vm) // 初始化事件系统,钩⼦函数等 initEvent(vm) // 编译slot、vnode initRender(vm) // 触发钩⼦ callHook(vm, 'beforeCreate') // 添加inject功能 initInjection(vm) // 完成数据响应性 props/data/watch/computed/methods initState(vm) // 添加 provide 功能 initProvide(vm) // 触发钩⼦ callHook(vm, 'created') // 挂载节点 if (vm.$options.el) { vm.$mount(vm.$options.el) } } // 挂载节点实现 function mountComponent(vm) { // 获 取 render function if (!this.options.render) { // template to render // Vue.compile = compileToFunctions let { render } = compileToFunctions() this.options.render = render } // 触发钩⼦ callHook('beforeMounte') // 初始化观察者 // render 渲 染 vdom, vdom = vm.render() // update: 根据 diff 出的 patchs 挂载成真实的 dom vm._update(vdom) // 触发钩⼦ callHook(vm, 'mounted') } // 更新节点实现 funtion queueWatcher(watcher) { nextTick(flushScheduleQueue) } // 清空队列 function flushScheduleQueue() { // 遍历队列中所有修改 for(){ // beforeUpdate watcher.before() // 依赖局部更新节点watcher.update() callHook('updated') } } // 销毁实例实现 Vue.prototype.$destory = function() { // 触发钩⼦ callHook(vm, 'beforeDestory') // ⾃身及⼦节点 remove() // 删除依赖 watcher.teardown() // 删除监听 vm.$off() // 触发钩⼦ callHook(vm, 'destoryed') }
j
3.Proxy 相⽐于 defineProperty 的优势
数组变化也能监听到
不需要深度遍历监听
let data = { a: 1 } let reactiveData = new Proxy(data, { get: function(target, name){ // ... }, // ... })
4. vue-router
mode
hash
history
跳转
this.$router.push()
<router-link to=""></router-link>
占位
<router-view></router-view>
5. vuex
state : 状态中⼼
mutations : 更改状态
actions : 异步更改状态
getters : 获取状态
modules : 将 state 分成多个 modules ,便于管理