UNPKG

hc-web-log-mon

Version:

基于 JS 跨平台插件,为前端项目提供【 行为、性能、异常、请求、资源、路由、曝光、录屏 】监控手段

89 lines (84 loc) 2.82 kB
import { Dep } from './dep' import { computedMap } from './computed' import { AnyFun, Options, Proxy } from './types' const targetStack: Watcher[] = [] function pushTarget(_target: Watcher) { if (Dep.target) targetStack.push(Dep.target) Dep.target = _target } function popTarget() { Dep.target = targetStack.pop() } export class Watcher { vm: any computed: boolean watch: boolean proxy: Proxy dep: Dep | undefined getter: AnyFun | undefined callback: AnyFun | undefined constructor(vm: any, options: Options, getter?: AnyFun) { const { computed, watch, callback } = options this.getter = getter // 获取值函数 this.computed = computed || false // 是否为计算属性 this.watch = watch || false // 是否为监听属性 this.callback = callback // 回调函数,专门给watch用的 this.proxy = { value: '', // 存储这个属性的值,在不需要更新的时候会直接取这个值 dirty: true // 表示这个属性是否脏了(脏了代表需要重新运算更新这个值) } this.vm = vm if (computed) { this.dep = new Dep() } else if (watch) { this.watchGet() } else { this.get() } } update(oldValue: any) { if (this.computed) { // 更新计算属性(不涉及渲染) this.dep!.notify() } else if (this.watch) { // 触发watch // this.watchGet() if (oldValue !== this.proxy.value) { this.callback && this.callback(this.proxy.value, oldValue) } } else { // 更新data, 触发依赖其的属性更新 this.get() } } get() { // 存入当前上下文到依赖(表示当前是哪个属性在依赖其他属性,这样在其他属性发生变化时就知道应该通知谁了) pushTarget(this) // 目前只有计算属性才会调用 get 方法 const value = this.computed ? computedMap.get(this.vm)!.call(this.vm) : '' if (value !== this.proxy.value) { this.proxy.dirty = false // 标记为不是脏的数据 this.proxy.value = value // 缓存数据,在数据不脏的时候直接拿这个缓存值 } popTarget() // 取出依赖 return value } /** * 监听属性专用 - 拿到最新值并添加依赖 */ watchGet() { pushTarget(this) // 将当前上下文放入 Dep.target this.proxy.dirty = false // 设定不为脏数据 if (this.getter) { this.proxy.value = this.getter() // 设定值(在这个过程中就给上了依赖) } popTarget() // 取出上面放入 Dep.target 的上下文 } /** * 计算属性专用 - 添加依赖 * 其他值用到了这个计算属性就会被记录添加到依赖中 */ depend() { this.dep!.addSub() } }