欢迎访问 生活随笔!

凯发k8官方网

当前位置: 凯发k8官方网 > 前端技术 > vue >内容正文

vue

局部钩子能防全局钩子吗-凯发k8官方网

发布时间:2024/10/5 vue 32 豆豆
凯发k8官方网 收集整理的这篇文章主要介绍了 局部钩子能防全局钩子吗_vue你真的熟吗?来回答这几个问题试试 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

这个面向中高级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你真的熟吗?来回答这几个问题试试的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得凯发k8官方网网站内容还不错,欢迎将凯发k8官方网推荐给好友。

  • 上一篇:
  • 下一篇:
网站地图