美文网首页
vue的watcher

vue的watcher

作者: 看到这朵小fa了么 | 来源:发表于2020-04-02 15:23 被阅读0次

    user-watcher

    在页面中使用的watcher,即用户定义的watcher,用于观察一个属性的更新,支持数组定义多个,对象定义单个的形式,在initWatcher中进行watcher的初始化之后,在渲染函数进行数据的读取,触发依赖收集时会将user-watcher的依赖收集进去,data属性set更新时会被触发user-watcher所定义的回调函数(将新旧值传入),支持异步操作
    可选项:immediate deep sync

    • immediate为true时会将实例作为参数传入立即执行回调函数
    • deep 对对象、数组进行深度的依赖收集
    • sync 不把更新watcher放到nextTick队列 而是立即执行更新

    render-watcher

    每一个组件都有一个render-watcher当data/computed中的有被依赖的属性改变的时候会触发render-watcher的更新,表达式为function(){vm._update(vm.render(), hydrating)}

    • 使用:在组件嵌套中,props触发的关联更新等,如父组件会将子组件的watcher收集用于视图更新的触发
    • 初始化:渲染函数的watcher,mounted之后,实例化初始化染函数观察者并触发对render-wather的收集,渲染函数也是一个对象,初始化过程,生成render-tree,获取结果时收集render-watcher依赖,render-tree更新也就是需要重新渲染视图
    • 防止重新收集:this.depIds.has(dep.id)来避免重复依赖收集,因在渲染函数中,一个属性被引用多次是常见的
    • 更新:data更新触发依赖,同时会触发user-watcher对回调函数完成新旧数据的派发,最后触发render-watcher更新视图,所有的watcher默认都是在nextTick队列中进行异步更新的,当所有的突变完成之后,一次性的执行队列中所有观察者的更新方法,同时清空队列,这样 多次更新同一个watcher只会更新一次,而频繁的更新可以整合为一次

    computed-watcher

    • 使用:在initState阶段被初始化,具有缓存性质的惰性求值观察者,只有存在依赖性数据并且该数据更新了,computed值才会更新,否则就取缓存的值,依赖数据是data中的数据
      -初始化:computed 计算属性在mounted之后生成,实例化computed-watcher 初始化computed dirty属性为true,并不调用get方法读取属性
    • 计算:当渲染函数访问到computed属性,进行求值,并将dirty设置为false标识计算过,同时对依赖的属性读取时将computed-watcher当做依赖收集,并且订阅render-watcher,所以在内部数据触发set时会先计算后对比新旧值,有更新则重新渲染视图
    • 更新:内部依赖被触发后,设置dirty为true,通过判断this.dep.subs.length 有没有订阅者,如果有则进行取值的计算(计算后将dirty置为false),否则等待该值被引用才进行计算

    总结

    这三种watcher执行顺序为computed watcher => user watcher => render watcher,这样做 尽可能的保证了视图更新时数据是最新的
    收集依赖是在render tree渲染时读取render tree的结构,触发依赖的收集,每一次都只会对一个观察者进行操作,所以一个时间点只有一个Dep.tatget,说明这个观察者是依赖于当前的数据,就会把这个观察者添加到该数据的subs里面,会通过id来防止重复添加,同时会将依赖添加到自身的deps中以便通过set调用dep.notify()

    什么时候触发了依赖的收集
    • 准备:在created和beforeMounted之间生成了AST和render可执行函数,用到了compile的createCompiler生成对象结构的AST语法树,再通过generator调用了之前初始化的方法处理各种vue内置的方法&指令,如v-for v-if等,通过createElement、createTextVnode等生成虚拟DOM树,作为updateComponent函数返回

    • 渲染:在beforeMounted和mounted之间通过将执行这个函数,这个函数会将虚拟DOM渲染成真正的DOM,内含有patch的布丁算法,在执行过程中会触发渲染函数,这时会触发数据属性的get函数,而这个过程的观察者就是渲染函数,在渲染过程中添加数据的订阅者,watcher订阅者是Observer和Compiler之间的桥梁,将在自身实例化的时候将自己添加到dep当中,watcher自身有一个depend和update方法,待属性变动dep.notice通知调用自身的update方法触发Compile中绑定的回调

    实现:https://blog.csdn.net/wangweianger/article/details/80307819

    相关文章

      网友评论

          本文标题:vue的watcher

          本文链接:https://www.haomeiwen.com/subject/qpexphtx.html