精华内容
下载资源
问答
  • 主要介绍了Vue发布订阅模式实现过程图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • vue发布订阅者模式$emit、$on

    千次阅读 2019-07-21 11:19:10
    vue中自定义事件,就是用了发布订阅者模式,vm.$on通过自定义事件,事先订阅一件事,vm.$emit通过自定义事件发布消息,vm.$on会接收到。非父子组件数据传递,通常会用到这两个方法: 下边我们先来用js实现发布...

        家住南京的李先生,最近看上了一套房子,到了售楼处才发现,该楼盘放在早已售罄。好在售楼处工作人员王女士出于好心告知李先生,不久之后还会有一些尾盘推出,开发商在办理相关手续,手续办理好之后便可购买。但到底什么时候能办理好,目前无人知道。于是李先生记下了售楼处电话,每天都会打电话询问是否到了购买时间。除了李先生,还有它的朋友、七大姑八大姨也会每天定点咨询这个问题。一周之后,售楼处王女士决定辞职,原因厌倦了每天回答1000个相同内容的电话。。。

            当然,现实中没有那么愚蠢的销售公司,实际上故事是这样的:李先生把他的电话号码留给售楼处,售楼处工作人员答应他,新楼盘一推出会马上通知李先生,他的朋友及七大姑也把电话号码留在了售楼处,新楼盘一推出工作人员会翻开电话簿,依次遍历上边的电话号码,发送信息告知他们。。。

           在上边案例中,发送短信依次告知 就是一个典型的发布、订阅者模式;李先生和他的朋友及七大姑等购买的人都是订阅者,他们订阅了楼盘开售的消息。售楼处作为发布者,会在适合的时候遍历电话簿上的电话号码,依次给购房者发布消息。

          使用发布订阅者模式有着显著的优点:购房者不需要天天询问开售时间,,在适合的时间点,售楼处会通知这些消息的订阅者;购房者和售楼处之间不再强耦合在一起,只要有新的购房者出现时,只需要把电话号码留在售楼处即可;而售楼处不会关心购房者任何情况,不管购房者 是男 是女 是猪?还是外星人(黑人问号脸)。售楼处的任何变动也不会影响购买者(当然除卷钱跑路的)!只要售楼处记得发短信这件事即可。。。

     

    在vue中自定义事件,就是用了发布订阅者模式,vm.$on通过自定义事件,事先订阅一件事,vm.$emit通过自定义事件发布消息,vm.$on会接收到。非父子组件数据传递,通常会用到这两个方法:

    下边我们先来用js实现发布订阅者模式:(这种模式必须先订阅才能接收到信息,注意顺序!)

    function Center(){
    	//订阅(售楼)中心,把所有要买楼房的人统一放在一个对象里,形成一对多关系
    	//  {"eventName":[callback1,callback2,··· ···]}
    	// 属性eventName:是电话薄
    	// 属性值是一个数组,里边每一个函数就是订阅楼盘信息的人(购房者)
    	this.subscriptionCenter = {};
    }
    //on和emit都是公共方法,所以写在原型上了
    Center.prototype.on = function ( eventName , callback ){
    	if( this.subscriptionCenter[eventName] ){
    		this.subscriptionCenter[eventName].push(callback);
    	}else{
    		this.subscriptionCenter[eventName] = [callback];
    	}
    }
    Center.prototype.emit = function ( eventName , ...publishInfo ){
    	if( this.subscriptionCenter[eventName] ){
    		this.subscriptionCenter[eventName].forEach( cb=>cb( ...publishInfo ) )
    	}
    }
    var center = new Center();
    
    //subscription是电话薄,后边函数是李先生订阅的信息,等待售楼中心发出日期
    center.on("subscription",function MrLi(time){
    	console.log(`您好李先生,新楼盘于${time}开售`)//因为订阅了售楼中心的信息,所以能接收到售楼中心传过来的消息
    })
    //后边函数是李先生的朋友订阅的信息
    center.on("subscription",function friend(time){
    	console.log(`您好李先生的朋友,新楼盘于${time}开售`)
    })
    //后边函数是七大姑订阅的信息
    center.on("subscription",function aunt(time){
    	console.log(`您好七大姑,新楼盘于${time}开售`)
    })
    // 订阅(售楼)中心通过电话薄,给每一个订阅者(购房者)发送消息
    center.emit("subscription","2019年7月21日")

    执行结果:

    建议大家,把代码赋值到编辑器里边,方便查看理解。。。(有不懂得地方欢迎留言询问)

    再来看下vue中$emit用法:

    vm.$emit( "eventName" , [ ... params ] )

    触发当前组件的自定义事件,参数一:自定义事件名,参数二:发送的数据,可以是一个字符串或一个数组,其实在vue源码中,即使你传的是一个字符串参数,还是会转化为数组,只不过在最后自定义事件执行的时候,会使用handler.aplly( context, args)形式把参数传入自定义的方法。(最后我会分析下vm.$emit和vm.$on的源码)

    eg:先看下$emit的用法,在created中使用$on事先监听一个自定义方法,当按钮被点击,$emit这个方法会执行,事件名对应的自定义事件会被触发,也就是$on监听一个自定义方法被触发。

    <template>
      <div>
        <button @click="handleEmit">click</button>
      </div>
    </template>
    
    <script>
    export default {
     created() {
       // this.$on()可为监听的事件,绑定多个处理函数
      this.$on('defaultEvent', this.emitFn1)
     },
     methods: {
       emitFn1(value) {
         console.log(value)// '1'
       },
       handleEmit() {
         this.$emit('defaultEvent', '1')
       }
     }
    };
    </script>

     

    $on用法:事先监听实例上边的自定义事件(也就是监听上边defaultEvent事件),事件由$emit触发,参数二:处理方法,它会接收emit触发的自定义事件的所有参数。

    $emit("eventName",[...params])
    $on("event",function(...params){
    		
    })

    这里就要不举例了,大家可以自己写一写。。。

    源码分析:

    vm.$on

    源码:

    $on方法 是被定义在Vue的原型上,此方法接收2个参数——事件名、事件名对应的处理方法,开始会判断下事件名是否是数组,是数组则循环里边的事件名,依次转化为单个字符串形式,否说明是一个字符串,接下来看下实例中的_events[event]是否有值,有的话,会把处理方法push到数组中;没有值则把值设置为一个数组,再把处理方法push到数组中。

    从上边源码中可分析出:

    (1)vm.$on可绑定多个事件名,前提需要以数组类型定义,多个事件名可对应同一个处理方法。

    (2)实例上会有一个_events对象,对象key为$on绑定的事件名,值为一个数组,数组里边装的是处理方法。

     

    vm.$emit()

    源码:

    $emit方法 定义在Vue的原型上,在源码中只传了一个参数,事件名,为什么呢?先往下看,开始如果是开发环境,把事件名转小写,如果转小写的事件名与传进来的事件名不等 且 实例中的_events对象中有事件名对应的处理方法,会报警告,不会有结果输出,这种情况是定义在$on和$emit中的事件名不一样 或者 子组件触发一个自定义事件名与父组件绑定的自定义事件名不一致,会抛出以上警告。

    继续往下走,根据传进来事件名获取到实例的_events对象中的处理方法,如果有处理方法,掉用toArray方法,把$emit第一个参数(事件名)去掉,只留下参数二(传递的参数)args,并且会把参数二转化为一个数组,toArray方法最后我会介绍,接下来循环cbs数组执行 invokeWithErrorHandling(cbs[i], vm, args, vm, info) 方法,cbs[i]:事件处理方法; ags:传递的参数。

    invokeWithErrorHandling方法:

    invokeWithErrorHandling方法会去判断是否有args参数,有则把参数传到事件处理方法中并执行,没有则只执行事件处理方法。

    补充下:

    还有一种情况是没有$on监听,子组件向父组件传值,使用$emit,在父组件中的自定义标签中绑定子组件触发的自定义事件,触发相对应的函数,这样父组件也会拿到值,原因在于,在子组件created的时候,Vue实例中的_events对像中已经有值了,key:子组件要触发的自定义的事件名,value:对应父组件要触发的事件处理函数。

    export default {
        name:'homeSon',
        created() {
            console.log('son', this._events) // son {handleEmit: Array(1)}
        },
        methods: {
            click() {
                this.$emit('handleEmit', '1') 
            }
        }, 
    }

     

    toArray方法:

    在Vue源码中,单独写了这么一个方法,目的:把类数组(如:arguments)或字符串转化为数组,参数二是起始位,如果传start,会从start位置开始截取,截取到最后,左开右闭,i为循环圈数,ret为数组长度是i,有个小细节,之所以要用new Array 去构造一个数组,原因是可以动态传值,且值就是构造出来的数组长度 。

    展开全文
  • vue发布订阅者模式

    千次阅读 2020-01-13 10:54:07
    https://www.jianshu.com/p/2ec316ca0f8b
    展开全文
  • 发布订阅模式:也称作观察者模式,定义对象间的一对多的依赖关系,当一个对象的状态发 生改变 时,所有依赖于它的对象都将得到通知; 编码中常用的场景: //订阅事件 window.addEventListener('click',()=&...

    发布订阅模式:也称作观察者模式,定义对象间的一对多的依赖关系,当一个对象的状态发 生改变 时,所有依赖于它的对象都将得到通知;

    编码中常用的场景:
    //订阅事件
    window.addEventListener('click',()=>{
       
    	alert("监听到某事件")
    })
    
    //发布事件
    window
    展开全文
  • 订阅发布模式定义了一种一对多的依赖关系,让多个订阅者对象同时监听某一个主题对象。这个主题对象在自身状态变化时,会通知所有订阅者对象,使它们能够自动更新自己的状态。 比如addEventListener 这个api就是个...
  • zh众所周知,vue2.x版本是通过Object.defineProperty() 种的get进行拦截,set进行发送,其实这只是表面理解,实际运用的是JavaScript的 订阅者发布者模式。首先,了解一下什么是订阅者发布者模式 吧。w3c 上是...

    zh众所周知,vue2.x版本是通过Object.defineProperty() 种的get进行拦截,set进行发送, 

    其实这只是表面理解,实际运用的是 JavaScript 的  订阅者、发布者模式。

    首先,了解一下什么是  订阅者、发布者模式 吧。


    w3c 上是这么定义的 


    可以用一个图来理解 



    首先我们来实现一下使用原型链的写法吧

    //定义一个函数,用来承载
    
    function publisher () {
        //定义一个空数组用来接收传递过来数据
        this.arr = [];
    }
    
    publisher.prototype = {
        //订阅
        subscribe : function (fn) {
            //订阅将'订阅者'push到arr数组中
            this.arr.push (fn)
        },
        //解除订阅
        unSubscribe : function (fn) {
            //过滤订阅者,如果'订阅者'el存在arr数组中,就解绑订阅
            this.arr = this.arr.forEach(function (el) {
                if(el !== fn) {
                    return el;
                }
            })
        },
    
        //更新订阅内容
        upDate : function (o,thisObj) {
            //o => 剩余订阅者 
            var scoped = thisObj || window ;
            //或者
            var scoped = thisObj || this.subscribe;
            this.fns.forEach (function (el) {
                // scoped 可以随便设置,el最终会替换scoped,将o 剩余订阅者传递进arr数组,将
                   订阅的人的信息打印出来
                el.call(scoped,o)
            }) 
        }
    }
    
    
    //创建一个实例
    var newSubScribe = new publisher () ;
    
    //创建一个订阅者
    var user = function (data) {
        console.log (` 第一位订阅者 ${data} 订阅了。`)
    }
    
    //创建第二位订阅者
    var newUser = function (data) {
        console.log (` 第二位订阅者 ${data} 订阅了。`)
    }
    
    //绑定订阅
    newSubScribe.subscribe(user);
    
    newSubScribe.subscribe(newUser);
    
    //更新订阅内容,看下效果
    newSubScribe.upDate(`Z先生`);
    
    //解绑第一个订阅者
    newSubScribe.unSubscribe(user);
    
    //在更新下数据
    newSubScribe.upDate(`Z女士`);
    
    /*
        下面我们看下打印结果
    */
    复制代码


    可以看到,已经实现了,第一位订阅者没有了,只剩第二位 订阅者了,当然实现的方法有很多种,这只是其中一种使用原型链

    实现



    转载于:https://juejin.im/post/5c7f6efce51d45043849da2f

    展开全文
  • 观察者模式 目标者对象和观察者对象有相互依赖的关系,观察者对某个对象的状态进行观察,如果对象的状态发生改变,...Vue中响应式数据变化是观察者模式 每个响应式属性都有dep,dep存放了依赖这个属性的watcher,w...
  • 发布订阅模式中订阅者发布者没有关联,所以观察者模式中包含了发布订阅模式(watcher和deep) 2、数据传递 /** *1.vue是单向数据流 *2.Vue组件间传值的方式及之间的区别 *3.props和emit父组件向子...
  • 订阅者 发布者 信号中心 我们假定,存在一个“信号中心”,某个任务执行完成,就向信号中心发布(publish)一个信号,其他任务可以向信号中心订阅(subscribe)这个信号,从而知道什么时候自己可以开始执行。这就...
  • Vue 发布订阅模式

    2021-09-23 08:43:26
    发布订阅模式订阅者发布者,信号中心 我们假定,存在一个“信号中心”,某个任务执行完成,就向信号中心"发布"(publish)一个信号,其它任务可以向信号中心“订阅”(subscribe)这个信号,从而知道什么时候自己...
  • 发布 订阅模式 // 事件触发器 class EventEmitter { constructor () { // { 'click': [fn1, fn2], 'change': [fn] } this.subs = Object.create(null) } // 注册事件 $on (eventType, handler) { ...
  • 发布订阅模式和观察者模式 发布/订阅模式 发布/订阅模式 订阅者 发布者 信号中心 我们假定,存在一个“信号中心”,某个任务执行完成,就向信号中心“发布”(publish)一个信号,其他任务可以向信号中心“订阅...
  • 模拟 Vue 响应式原理。 准备工作 数据驱动 数据响应式 数据模型仅仅是普通的 JavaScript 对象,而当我们修改数据时,视图会进行更新,避免了繁琐的 DOM 操作,提高开发效率。 双向绑定 数据改变,视图改变;...
  • 要搞清楚vue中的双向数据绑定原理,就必须理解什么是发布订阅者模式!! 1、首先想好谁是发布者、谁是订阅者(例如NBA专栏就是发布者,NBA球迷就是订阅者) 2、然后给发布者添加一个缓存列表,用于存放回调函数...
  • vue使用的「发布-订阅模式是什么

    千次阅读 2020-05-05 18:11:46
    发布-订阅模式也叫观察者模式
  • class Vue { constructor(options) { // 获取到根元素 this.el = document.querySelector(options.el) // #root // 获取到数据 this.data = options.data ...
  • 发布/订阅模式和观察者模式通常被混为一谈,但它们在Vue中有着不同的应用场景。 发布/订阅模式核心: 订阅者 发布者 信号中心(事件中心) 我们假定:存在一个“信号中心”,某个任务执行完成,就向信号中心“发布...
  • 发布订阅模式 $ 定义 基于一个自定义事件通道,收集与之相关的订阅成员,通过发布自定义事件的方式通知各个订阅成员。 $ Vue中的语法 // Vue 自定义事件 let vm = new Vue() // 注册事件(订阅消息) vm.$on('data...
  • 观察者模式 ...发布者内部需要一个属性去记录所有的订阅者,也就是所该属性是一个数组 还需要一个方法去添加所有的订阅者到数组中存储起来 还需要一个方法当事件发生时去通知所有订阅者执行update
  • 结合 Vue 源码谈谈发布-订阅模式

    千次阅读 2018-10-21 10:23:23
    最近的工作学习中接触到了发布-订阅模式。... 订阅函数,添加订阅者,传入发布时要执行的函数,可能会携额外参数 一个缓存订阅者以及订阅者的回调函数的列表 取消订阅(需要分情况讨论) 这么看下来,其实就像 ...
  • vue订阅者模式

    2019-03-18 20:54:00
    这是订阅者1 ' ) }) obj.addListener( ' click ' , function (e){ console.log(e) console.log( ' 这是订阅者2 ' ) }) var fn1 = function (){ console.log( ' 这是订阅者3 ' ) } obj....
  • 发布订阅模式 目标: 解耦, 让各个模块之间没有紧密的联系 现在的处理办法是 属性在更新的 时候 调用 mountComponent 方法. 问题: mountComponent 更新的是什么??? (现在) 全部的页面 -> 当前虚拟 DOM 对应的页面 ...
  • vue.js的发布者与订阅者

    千次阅读 2020-03-24 20:39:01
    $once 订阅者只订阅一次消息(比如我订阅了一个公众号,它只给我推送了一个内容,我就把它取消订阅了,后续不会再收到) $off 取消订阅(所有的订阅者只接受一次消息) 代码具体介绍 /*--------------------------...
  • 有人说观察者模式发布订阅的升级版,也有人说发布订阅是进阶版的观察者模式,但是无论是观察者模式还是发布订阅模式,它们都是定义了对象之间的一种一对多的依赖关系。 观察者模式 当目标对象的状态发生改变时,...
  • 。。 转载于:https://www.cnblogs.com/stephenleee/p/10298939.html
  • 数据劫持+发布订阅者模式 数据劫持 new vue时候拿到data中返回的对象,通过object.key().forEach()遍历,给原来对象中的属性通过object.defineProperty重新定义赋值。通过这个方法在对象使用这个属性的时候(obj...
  • 观察者模式 目标者对象和观察者对象有相互依赖的关系,观察者对某个对象的状态进行观察,如果对象的状态发生...Vue中响应式数据变化是观察者模式 每个响应式属性都有dep,dep存放了依赖这个属性的watcher,watcher...
  • class Event { constructor (){ this .events = {} ...// vue中数据劫持结合发布/...对发布订阅者的通俗理解 订阅可以理解为寄存,发布理解为寄存的拿出调用,可以寄存很多个,拿出很多个 观察者模式主要是监听
  • 最近空闲时间手撸代码实现了发布订阅模式,可以进行组件通信。 话不多说,直接上代码 /** * Created by laichengliang on 2021/04/13. */ const center = {} // 事件监听 center.on = (eventName, callback) ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 9,415
精华内容 3,766
关键字:

vue的发布订阅者模式

vue 订阅