局部钩子能防全局钩子吗_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') }}
尾声
汗--!没想到才写一半就这么多内容了,为了阅读体验,决定分上下俩部分发。后续文章可以关注我,翻看历史文章~
局部钩子能防全局钩子吗_Vue你真的熟吗?来回答这几个问题试试相关推荐
- 局部钩子能防全局钩子吗_Django局部钩子和全局钩子
Ⅰ 局部钩子的使用 在自定义的Form类中写 clean_字段名 取出字段的真正值 做复杂判断 如果判断失败,抛出ValidationError 如果通过,return 判断的字段 判断用户名是否以字 ...
- 局部钩子能防全局钩子吗_阿特的钩子成为队友的噩梦,毫无游戏体验感,小夏:当场哭了出来...
关注过文森特打游戏的人都清楚,阿特本命英雄是荣耀行刑官德莱文,而他的好基友小夏一直是他的忠实辅助,每局游戏都选个魂锁典狱长锤石,陪伴在阿特的身边,不离不弃,不得不说这两位搭档的默契已经达到了炉火纯青的 ...
- 局部钩子能防全局钩子吗_这个英雄还值得我们去练吗?百里玄策打法难点解析...
本赛季荣耀,玄策胜率80% 百里玄策一直是芃叔的本命英雄,小疯子痞帅的人物特点,加上技能的控制和狂暴效果一直深受广大玩家的喜爱.但是在最近一次调整之后,百里玄策的强度从以前的T1沦为T2,胜率也是跌至 ...
- 银行登录控件仿制--防钩子,防嗅探
银行登录控件仿制--防全局钩子,防嗅探 类似于支付宝登录控件.工商.招商银行登录控件,这个是一个DLL钩子,用于注入其他进程 另外有一个控件,用来模拟INPUT控件,近期发布! 变量定义 unit h ...
- 【C++】代码实现:全局钩子注入技术
一.概述 在 Windows 中大部分的应用程序都是基于消息机制的,它们都有一个过程函数,根据不同的消息完成不同的功能. Windows 操作系统提供的钩子机制就是用来截获和监视系统中这些消息的. ...
- Windows 全局钩子 Hook 详解
监控程序的实现 我们发现一些木马或其他病毒程序常常会将我们的键盘或鼠标的操作消息记录下来然后再将它发到他们指定的地方以实现监听.这种功能其他是利用了全局钩子将鼠标或键盘消息进行了截取,从而 ...
- java hook全局钩子_钩子(hook)
钩子(hook)编程 一.钩子介绍 1.1钩子的实现机制 钩子英文名叫Hook,是一种截获windows系统中某应用程序或者所有进程的消息的一种技术.下图是windows应用程序传递消息的过程: 如在 ...
- Django13-ModelForm中的is_valid及局部钩子、全局钩子源码解析
1.查看is_valid方法,返回self.is_bound和非self.errors def is_valid(self):"""Returns True if the ...
- 基于Ajax提交formdata数据、错误信息展示和局部钩子、全局钩子的校验。
formdata重点: 实例化FormData这个类 循环serializeArray可以节省代码量 图片要用$('#id')[0].files[0]来获得 加上contentType:false和p ...
最新文章
- Android Popwindow 使用
- 你的vs.net 2005过期了吗?
- Silverlight
- 今日定工资,不知是涨是跌,最迟明晚反馈
- First、FirstOrDefault、Single、SingleOrDefault 的区别
- 数据结构学习笔记(一)——《大话数据结构》
- threejs渲染器剔除模式
- 让360安全浏览器默认使用谷歌内核
- 别瞎找了,你要的C语言经典示例都在这~
- django基础入门(1)django基本配置
- 关于new 和delete的灾祸
- android 悬浮组件,Android 悬浮组件
- MATLAB常用三角函数
- Windows:定时/进程结束执行命令
- Eplan教程——线束的使用
- csm和uefi_传统bios引导与uefi引导之比较
- ipadpro尺寸的html,iPad Pro尺寸到底有多大?
- 【学习笔记】Stern-Brocot Tree
- 怪异,漂亮的几个数学恒等式(转)
- c语言中断函数作用,进一步理解中断函数
热门文章
- String All Methods
- 判定一个点是否在三角形内
- 第一次走绿道,从长岭陂到梅林水库
- HOWTO:如何在代码中获取安装包目标机上的Windows Installer(MSI)版本
- 计算机机等级考试四级模拟,《全国计算机等级考试上机考试模拟考场-四级》.pdf...
- 腐蚀rust研究台抽奖_延迟焦化装置的腐蚀风险分析
- c语言里的%p的作用,C语言中geiwei=m%10什么意思,求解!
- python写彩票抓取_Python|爬取彩票数据
- linux如何更改服务器时间格式,Linux中date命令,格式化输出,时间设置
- c语言程序中unit怎么定义,c ++中的一个定义规则(One definition rule in c++)