Vue发布-订阅者模式
1、vue响应原理:
vue.js采用数据劫持结合发布-订阅者模式,通过Object.defineProperty()来劫持data中各个属性的setter、getter,在数据变动时,发布消息给订阅者,触发响应的监听回调。
(setter和getter是对象的存储器属性,是一个函数,用来获取和设置值)
2、发布-订阅者模式的作用:
处理一对多的场景,应用于不同情况下的不同函数调用
优点:低耦合性,易于代码维护;
缺点:若订阅的消息未发生,需消耗一定的时间和内存。
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Vue发布-订阅模式</title> </head> <body> <div id="app"> 订阅试图-1:<span class="box-1">第一个值</span> 订阅试图-2:<span class="box-2">第二个值</span> </div> <script> //订阅器模型 var Dep = { list: {}, listen: function (key, fn) { (this.list[key] || (this.list[key] = [])).push(fn); }, trigger: function () { var key = Array.prototype.shift.call(arguments); fns = this.list[key]; if (!fns || fns.length == 0) return; for (var i = 0, fn; fn = fns[i++];) { fn.apply(this, arguments);//发布消息附带的参数 } } }; //劫持的方法 Object.defineProperty方法,给对象的属性赋值 var dataHijack = function ({ data, tag, datakey, selector }) { debugger var value = ''; el = document.querySelector(selector); Object.defineProperty(data, datakey, { //拿到数据 get: function () { console.log('我获取到值了'); return value; }, //设置数据 set: function (newVal) { console.log('我设置值了'); value = newVal; Dep.trigger(tag, newVal); //发布消息,更新变化 } }) //绑定观察者 Dep.listen(tag, function (text) { el.innerHTML = text; }) }; var dataObj = {}; //数据 //数据劫持 dataHijack({ data: dataObj, tag: 'view-1', datakey: 'one', selector: '.box-1' }); dataHijack({ data: dataObj, tag: 'view-2', datakey: 'two', selector: '.box-2' }); </script> </body> </html>
// jquery中的发布-订阅者 //创建一个事件池 $.Callback() let $pond= $.Callback(); $('.submit').click(function(){ //发布 点击的时候通知事件池中的方法执行,同时传递实参 $pond.fire(100,200); }); let fn1=function(){console.log(1)} let fn2=function(){console.log(2)} let fn3=function(n,m){console.log(3,n+m)} //把需要做的事情添加到事件池中 //事件池相当于一个登记册,把所有订阅者收集到上面 $pond.add(fn1); $pond.add(fn2); $pond.add(fn3);