狗万官网酒店 > 狗万官网下载 > 穿越图带你深入了解vue的号召力式原理_vue.js

穿越图带你深入了解vue的号召力式原理_vue.js

来源: 2019-08-04 19:43 我来投稿 参与评论
这篇文章主要介绍了穿越图带你深入了解vue的号召力式原理,文中通过示范代码介绍的独特详细,对大家的上学或者工作具有原则性的参考学习价值,

前言

如果自己去落实数据驱动的货仓式,如何解决一下几个问题:

  • 交通过什么手段去领略我之数目变了?
  • 交通过什么东西去同步更新视图?
  • 多少劫持――obvserver

    咱需要了解数据的获取和转移,多少劫持是最基础的手法。在Obeserver外方,咱可以见到代码如下:

    Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get: function reactiveGetter () {
    // ...
    },
    set: function reactiveSetter (newVal) {
    // ...
    }
    })

    穿越Object.defineProperty本条艺术,咱可以在数量发生改变或者获取的时光,插入一些自定义操作。同理,vue也是在这个艺术中做依赖收集和派发更新的。

    绑定和创新视图――watcher

    副初始化开始,咱渲染视图的时光,便会生成一个watcher,她是督促视图中数变化以及更新视图的。代码如下:

    // 在mount的生命钩子中
    new Watcher(vm, updateComponent, noop, {
    before () {
    if (vm._isMounted && !vm._isDestroyed) {
    callHook(vm, 'beforeUpdate')
    }
    }
    }, true /* isRenderWatcher */)

    当然,咱可以保留疑问:

  • watcher是怎么去更新视图的
  • 多少又是怎么和watcher联动起来的
  • 实际的绑定和创新的流程,咱到后续的依赖收集中讲解。

    咱先来说话响应式系统中涉及到的规划模式。

    通告订阅模式

    在公布订阅模式中,发布者和订阅者之间多了一下发布通道;另一方面从发布者接收事件,一边向订阅者发布事件;订阅者需要从事件通道订阅事件

    其一避免发布者和订阅者之间产生依赖关系

    vue的号召力式流程

    vue的号召力式系统借鉴了多少劫持和发表订阅模式。

    Vue用Dep表现一个中间者,解藕了Observer和Watcher之间的联系,有效两岸之成效更加明朗。

    那具体是如何来形成依赖收集和订阅更新的呢?

    依托收集过程

    依托收集的流程

    举个比喻

    <div id="app">
    {{ message }}
    {{ message1 }}
    <input type="text" v-model="message">
    <div @click="changeMessage">转移message</div> 
    </div>
    var app = new Vue({
    el: '#app',
    data: {
    message: '1',
    message1: '2',
    },
    methods: {
    changeMessage() {
    this.message = '2'
    }
    },
    watch: {
    message: function(val) {
    this.message1 = val
    }
    }
    })

    依托收集流程图:

    如何看懂这个依赖收集流程?重点在watcher代码中:

    get () {
    pushTarget(this)
    let value
    const vm = this.vm
    try {
    value = this.getter.call(vm, vm)
    } catch (e) {
    // 大概
    } finally {
    if (this.deep) {
    traverse(value)
    }
    popTarget()
    this.cleanupDeps()
    }
    return value
    }

    合同的这个this.getter有两种,一种是key值的getter艺术,还有一种是expOrFn,比如mounted外方传播的updateComponent。

    如何防止反复收集

    咱不妨想想什么才算是重复收集了?

    作者想到一种情形:就是dep数组中,出现了多个一样的watcher。

    比如renderWatch就不难把重复收集,因为我们在html模版中,会重复使用data中的某个变量。那他是如何去重的呢?

    1、只有watch在实行get时,触发的取数操作,才会把收集

    Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get: function reactiveGetter () {
    const value = getter ? getter.call(obj) : val
    if (Dep.target) {
    dep.depend()
    // ...
    }
    return value
    },
    set: function reactiveSetter (newVal) {
    // ...
    dep.notify()
    }
    })

    顶只有Dep.target本条存在的时光才进行依赖收集。Dep.target本条值只有在watcher实行get艺术的时光才会生活。

    2、在dep.depend的时光会判断watch的id

    depend () {
    if (Dep.target) {
    Dep.target.addDep(this)
    }
    }
    addDep (dep: Dep) {
    const id = dep.id
    if (!this.newDepIds.has(id)) {
    this.newDepIds.add(id)
    this.newDeps.push(dep)
    if (!this.depIds.has(id)) {
    dep.addSub(this)
    }
    }
    }

    咱会发现,在depend经过中,会有一番newDepIds扮演记录已经存入的dep的id,顶一个watcher已经把该dep存过时,便不再会进行依赖收集操作。

    派发更新过程

    采访流程讲完了,不妨在倾听更新流程。

    订阅更新的流程

    成熟例子

    <div id="app">
    {{ message }}
    {{ message1 }}
    <input type="text" v-model="message">
    <div @click="changeMessage">转移message</div> 
    </div>
    var app = new Vue({
    el: '#app',
    data: {
    message: '1',
    message1: '2',
    },
    methods: {
    changeMessage() {
    this.message = '3'
    }
    },
    watch: {
    message: function(val) {
    this.message1 = val
    }
    }
    })

    依托收集的终极结果:

    顶触发click事件的时光,便会触发订阅更新流程。

    订阅更新流程图:

    顶renderWatch实行更新的时光,归来调用beforeUpdate生命钩子,接下来执行patch艺术,开展视图的改观。

    如何防止反复更新

    如何去防止反复更新呢?renderWatch会把广大dep开展采访,如果视图多次渲染,会造成性能问题。

    其实问题的关在在于――queueWatcher

    在queueWatcher外方有两个操作:扮演重和异步更新。

    function queueWatcher (watcher) {
    const id = watcher.id
    if (has[id] == null) {
    has[id] = true
    queue.push(watcher)
    // ...
    if (!waiting) {
    waiting = true
    // ...
    nextTick(flushSchedulerQueue)
    }
    }
    }

    其实queueWatcher很简单,名将一切watch采访到一个数组当中,接下来去重。

    这样至少可以避免renderWatch频繁更新。

    比如上述例子中的,message和message1都有一个renderWatch,但是只会执行一次。

    异步更新也得以保证当一个事件结束以后,才会触发视图层的创新,也能防止renderWatch一再更新

    末了

    文章讲述了响应式流程的缘故,代码细节并未深入,

    上述就是本文的方方面面内容,瞩望对大家的上学有所帮助,也愿意大家多多支持脚本的师。

    义务编辑:狗万官网酒店
     
     
    0% (0)
     
     
    0% (0)
    机长评论( ) 请自觉遵守互联网相关的富民政策法规,不准发布色情、暴力、反动的议论。
    地名: 匿名?

          
      &lt;source id="7ee222d9"&gt;&lt;/source&gt;
    1.