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);