局部钩子能防全局钩子吗-凯发k8官方网
这个面向中高级web前端的面经系列文章,到此便接近尾声了。是不是还有继续出,这个要看接下来的时间安排了。
小团体有个朋友说,他准备更新一些android-kotlin从入门到上手写业务的文章。所以关注我的web前端的朋友们,不着急,先休息休息,消化消化之前的文章,提前预祝跳槽的朋友,有个好东家~!
本系列文章链接如下:
“金三银四”,让我们愉快的开始准备web面经吧:css篇
“金三银四”,让我们愉快的开始准备web面经吧:javascript-上
中高端web前端面试题,直击bat:javascript篇
元宵节,猿宵节,写代码之余面经走一波:javascript篇
通往中高端web前端:浏览器篇
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会将编译成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): 不销毁,缓存,组件激活与失活
- 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')}3. 数据响应(数据劫持)
看完生命周期后,里面的watcher等内容其实是数据响应中的一部分。数据响应的实现由两部分构成: 观察者( watcher ) 和 依赖收集器( dep ),其核心是 defineproperty这个方法,它可以 重写属性的 get 与 set 方法,从而完成监听数据的改变。
- observe (观察者)观察 props 与 state
- 遍历 props 与 state,对每个属性创建独立的监听器( watcher )
- 使用 defineproperty 重写每个属性的 get/set(definereactive)
- get: 收集依赖
- dep.depend()watcher.adddep()
- set: 派发更新
- dep.notify()
- watcher.update()
- queenwatcher()
- nexttick
- flushschedulequeue
- watcher.run()
- updatecomponent()
大家可以先看下面的数据相应的代码实现后,理解后就比较容易看懂上面的简单脉络了。
let data = {a: 1}// 数据响应性observe(data)// 初始化观察者new watcher(data, 'name', updatecomponent)data.a = 2// 简单表示用于数据更新后的操作function updatecomponent() { vm._update() // patchs}// 监视对象function observe(obj) { // 遍历对象,使用 get/set 重新定义对象的每个属性值 object.keys(obj).map(key => { definereactive(obj, key, obj[key]) })}function definereactive(obj, k, v) { // 递归子属性 if (type(v) == 'object') observe(v) // 新建依赖收集器 let dep = new dep() // 定义get/set object.defineproperty(obj, k, { enumerable: true, configurable: true, get: function reactivegetter() { // 当有获取该属性时,证明依赖于该对象,因此被添加进收集器中 if (dep.target) { dep.addsub(dep.target) } return v }, // 重新设置值时,触发收集器的通知机制 set: function reactivesetter(nv) { v = nv dep.nofify() }, })}// 依赖收集器class dep { constructor() { this.subs = [] } addsub(sub) { this.subs.push(sub) } notify() { this.subs.map(sub => { sub.update() }) }}dep.target = null// 观察者class watcher { constructor(obj, key, cb) { dep.target = this this.cb = cb this.obj = obj this.key = key this.value = obj[key] dep.target = null } adddep(dep) { dep.addsub(this) } update() { this.value = this.obj[this.key] this.cb(this.value) } before() { callhook('beforeupdate') }}汗--!没想到才写一半就这么多内容了,为了阅读体验,决定分上下俩部分发。后续文章可以关注我,翻看历史文章~
总结
以上是凯发k8官方网为你收集整理的局部钩子能防全局钩子吗_vue你真的熟吗?来回答这几个问题试试的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇:
- 下一篇: