主题
Vue
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更新 flushScheduleQueuewatcher.before: 触发beforeUpdate钩子 -watcher.run(): 执行watcher中的notify, 通知所有依赖项更新UI- 触发
updated钩子: 组件已更新 actived/deactivated(keep-alive): 不销毁, 缓存, 组件激活与失活destroybeforeDestroy: 销毁开始- 销毁自身且递归销毁子组件以及事件监听
remove(): 删除节点watcher.teardown(): 清空依赖vm.$off(): 解绑监听
- destroyed : 完成后触发钩子
上面是 vue 的声明周期的简单梳理,接下来我们直接以代码的形式来完成 vue 的初始化
js
new Vue({});
// 初始化Vue实例
function initVue() {
// 挂载属性
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");
}
// 更新节点实现
function queueWatcher(watcher) {
nextTick(flushScheduleQueue);
}
// 清空队列
function flushScheduleQueue() {
// 遍历队列中所有修改
for (let i = 0; i < watcherQueue.length; i++) {
// beforeUpdate
watcher.before();
// 依赖局部更新节点
watcher.update();
callHook("updated");
}
}
// 销毁实例实现
Vue.prototype.$destory = function () {
// 触发钩子
callHook(vm, "beforeDestory");
// 自身及子节点
remove();
// 删除依赖
watcher.teardown();
// 删除监听
vm.$off();
// 触发钩子
callHook(vm, "destoryed");
};3. Proxy 相比于 defineProperty 的优势
- 数组变化也能监听到
- 不需要深度遍历监听
js
let data = { a: 1 };
let reactiveData = new Proxy(data, {
get: function (target, name) {
// ...
},
// ...
});4. vue-router
mode
hashhistory
跳转
this.$router.push()<router-link to=""></router-link>
占位
vue
<router-view></router-view>5. vuex
state: 状态中心mutations: 更改状态actions: 异步更改状态getters: 获取状态modules: 将state分成多个modules,便于管理
