网站地图    收藏   

主页 > 前端 > vue教程 >

通过图带你深入了解vue的响应式原理

来源:自学PHP网    时间:2019-07-23 15:23 作者:小飞侠 阅读:

[导读] 通过图带你深入了解vue的响应式原理...

前言
数据劫持——obvserver

Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get: function reactiveGetter () {
// ...
},
set: function reactiveSetter (newVal) {
// ...
}
})绑定和更新视图——watcher
// 在mount的生命钩子中
new Watcher(vm, updateComponent, noop, {
before () {
if (vm._isMounted && !vm._isDestroyed) {
callHook(vm, 'beforeUpdate')
}
}
}, true /* isRenderWatcher */)
  
  • 数据又是怎么和watcher联动起来的发布订阅模式
    vue的响应式流程
    依赖收集过程
    {{ message }} {{ message1 }}
    改变message
    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
    }
    

    如何防止重复收集

    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()
    }
    })
    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)
    }
    }
    }
    

    派发更新过程

    {{ message }} {{ message1 }}
    改变message
    var app = new Vue({
    el: '#app',
    data: {
    message: '1',
    message1: '2',
    },
    methods: {
    changeMessage() {
    this.message = '3'
    }
    },
    watch: {
    message: function(val) {
    this.message1 = val
    }
    }
    })当renderWatch执行更新的时候,回去调用beforeUpdate生命钩子,然后执行patch方法,进行视图的变更。
    function queueWatcher (watcher) {
    const id = watcher.id
    if (has[id] == null) {
    has[id] = true
    queue.push(watcher)
    // ...
    if (!waiting) {
    waiting = true
    // ...
    nextTick(flushSchedulerQueue)
    }
    }
    }结尾

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

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持自学php网。

    自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习

    京ICP备14009008号-1@版权所有www.zixuephp.com

    网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com

    添加评论