最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 从first commit开始学Vue源码之发布订阅模式(一)

    正文概述 掘金(哇哦谢谢你)   2021-01-08   514

    发布订阅模式是vue使用的最关键的一个模式之一,也是vue实现响应式的关键。因此我们先从发布订阅模式学起。

    发布订阅模式概念:发布订阅模式,也可以叫做:让我康康模式,或者凑热闹模式,就是你关注的事情发生改变了,第一时间通知你,最常见的就是微博上的关注,知乎上的关注,有两种推送方式一种是被动推送,只有你主动去看了,才会把你关注的人最新消息发给你。还有一种是主动推送模式,一有新情况就推新消息给你,比如手机经常来的通知:你关注的新番更新啦!(没有巨人第五话看我快死了,莱纳你快坐啊!)

    我来逝世:

    0.1v简单版本,先定义两个类,发布者和订阅者

    发布者:

    export default class Publisher {
        constructor(name) {
            this.name = name
            this.sub = []
        }
    /**
     * update方法
     */
        update() {
            console.log(`${this.name}我发布啦!`)
            for(let i = 0; i < this.sub.length; i++) {
                this.sub[i].afterUpdate()
            }
        }
    /**
     *  
     */ 
        addSub(sub) {
            this.sub.push(sub)
            console.log(`${sub.name}已经订阅!`)
        }
    
        removeSub(sub) {
            let index = this.sub.findIndex(sub)
            this.sub.splice(index, 1)
        }
    }
    

    订阅者:

    export default class Subscriber {
        constructor(name) {
            this.name = name
        }
    
        afterUpdate() {
            console.log(`${this.name}我爱看进击的巨人!`)
        }
    }
    

    接下来是测试代码:我们新建一个巨人发布者,然后我、小明、小红都订阅了它,当巨人更新时应该能触发我们的更新后执行函数。

    import Publisher from './publisher.mjs'
    import Subscriber from './subscriber.mjs'
    
    const TITAN = new Publisher(`Attack on Titan`)
    let me = new Subscriber(`bobo`)
    let ming = new Subscriber(`xiaoming`)
    let hong = new Subscriber(`xiaohong`)
    
    TITAN.addSub(me)
    TITAN.addSub(ming)
    TITAN.addSub(hong)
    
    TITAN.update()
    

    测试结果:从first commit开始学Vue源码之发布订阅模式(一)

    这时看起来有些古怪,讲道理,订阅应该是订阅者去订阅,这么成发布者订阅了?而且我、小明、小红也许不想执行相同的方法,我想更新后立马就看,小明吃中饭时看,小红想晚上看,因此我们给订阅者添加订阅方法并给构造函数多加一个参数接受自定义函数。

    订阅者改动如下:

    export default class Subscriber {
        constructor(name, fn) {
            this.name = name
            this.fn = fn
        }
    
        afterUpdate() {
            this.fn()
        }
    
        subscribe(pub) {
            pub.addSub(this)
            console.log(`${pub.name}被我${this.name}订阅啦!`)
        }
    }
    

    测试代码改动如下:

    import Publisher from './publisher.mjs'
    import Subscriber from './subscriber.mjs'
    
    const TITAN = new Publisher(`Attack on Titan`)
    let me = new Subscriber(`bobo`, function(){console.log(`${this.name}要立刻看`)})
    let ming = new Subscriber(`xiaoming`, function(){console.log(`${this.name}到中午看`)})
    let hong = new Subscriber(`xiaohong`, function(){console.log(`${this.name}到晚上看`)})
    
    me.subscribe(TITAN)
    ming.subscribe(TITAN)
    hong.subscribe(TITAN)
    
    TITAN.update()
    

    测试结果:从first commit开始学Vue源码之发布订阅模式(一)

    难道我就订阅一个《进击的巨人》?我还想要订阅《BeatStars》!我还想看史莱姆装杯!继续修改测试代码:

    import Publisher from './publisher.mjs'
    import Subscriber from './subscriber.mjs'
    
    const TITAN = new Publisher(`Attack on Titan`)
    const BEATSTRAS = new Publisher(`BEATSTARS`)
    const SLIME = new Publisher(`Slime`)
    let me = new Subscriber(`bobo`, function(){console.log(`${this.name}要立刻看`)})
    let ming = new Subscriber(`xiaoming`, function(){console.log(`${this.name}到中午看`)})
    let hong = new Subscriber(`xiaohong`, function(){console.log(`${this.name}到晚上看`)})
    
    me.subscribe(TITAN)
    ming.subscribe(TITAN)
    hong.subscribe(TITAN)
    
    
    me.subscribe(BEATSTRAS)
    me.subscribe(SLIME)
    
    TITAN.update()
    

    测试结果:从first commit开始学Vue源码之发布订阅模式(一)

    这时候还有一个问题,我想要立刻看进击的巨人,中午看beatstars,晚上看史莱姆。可是他们一更新,我执行的都是立马看,看的我好累哦!因此我们要做好时间管理!

    对每一个妹子,哦,错了,对订阅的每部动漫,都采取不同的观看方式,而不是一直的观看方式。继续修改订阅者和测试代码:

    export default class Subscriber {
        constructor(name) {
            this.name = name
            this.subFnArr = new Map()
        }
    
        afterUpdate(pub) {
           let fn = this.subFnArr.get(pub).bind(this)
           fn()
        }
    
        subscribe(pub, fn) {
            pub.addSub(this)
            this.subFnArr.set(pub, fn)
            console.log(`${pub.name}被我${this.name}订阅啦!`)
        }
    }
    
    import Publisher from './publisher.mjs'
    import Subscriber from './subscriber.mjs'
    
    const TITAN = new Publisher(`Attack on Titan`)
    const BEATSTRAS = new Publisher(`BEATSTARS`)
    const SLIME = new Publisher(`Slime`)
    let me = new Subscriber(`bobo`)
    let ming = new Subscriber(`xiaoming`)
    let hong = new Subscriber(`xiaohong`)
    
    me.subscribe(TITAN, function(){console.log(`${this.name}要立刻看`)})
    ming.subscribe(TITAN, function(){console.log(`${this.name}到中午看`)})
    hong.subscribe(TITAN,  function(){console.log(`${this.name}到晚上看`)})
    
    
    me.subscribe(BEATSTRAS, function(){console.log(`${this.name}到中午边吃饭边看`)})
    me.subscribe(SLIME, function(){console.log(`${this.name}到晚上996下班回家看`)})
    
    TITAN.update()
    BEATSTRAS.update()
    SLIME.update()
    

    测试结果: 从first commit开始学Vue源码之发布订阅模式(一)


    起源地下载网 » 从first commit开始学Vue源码之发布订阅模式(一)

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元