<source id="7ee222d9"></source>
  1.     


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

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

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

            前言

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

          2. 交通过什么手段去领略我之数目变了?
          3. 交通过什么东西去同步更新视图?
          4. 多少劫持――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 */)

            当然,咱可以保留疑问:

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

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

            通告订阅模式

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

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

            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)
            机长评论( ) 请自觉遵守互联网相关的富民政策法规,不准发布色情、暴力、反动的议论。
            地名: 匿名?