1. 程式人生 > 其它 >釋出者訂閱者模式(vue雙向繫結原理)

釋出者訂閱者模式(vue雙向繫結原理)

 1 最重要的就是Object.defineProperty(a,b,c).
a是要操作的物件,b是要新增或修改的屬性,c是屬性的值(用value:xx表示)
具體看連結:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

  <!DOCTYPE html> 2 <html lang="zh-CN"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Vue釋出-訂閱模式</title> 6
</head> 7 <body> 8 <div id="app"> 9 訂閱試圖-1:<span class="box-1">第一個值</span> 10 訂閱試圖-2:<span class="box-2">第二個值</span> 11 </div> 12 <script> 13 //訂閱器模型 14 var Dep = { 15 list: {}, 16 listen: function
(key, fn) { 17 (this.list[key] || (this.list[key] = [])).push(fn); 18 }, 19 trigger: function () { 20 var key = Array.prototype.shift.call(arguments); 21 fns = this.list[key]; 22 if (!fns || fns.length == 0) return
; 23 for (var i = 0, fn; fn = fns[i++];) { 24 fn.apply(this, arguments);//釋出訊息附帶的引數 25 } 26 } 27 }; 28 29 //劫持的方法 Object.defineProperty方法,給物件的屬性賦值 30 var dataHijack = function ({ data, tag, datakey, selector }) { 31 // debugger 32 var value = ''; 33 el = document.querySelector(selector); 34 Object.defineProperty(data, datakey, { 35 //拿到資料 36 get: function () { 37 // console.log('我獲取到值了'); 38 return value; 39 }, 40 //設定資料 41 set: function (newVal) { 42 // console.log('我設定值了'); 43 value = newVal; 44 Dep.trigger(tag, newVal); //釋出訊息,更新變化 45 } 46 }) 47 //繫結觀察者 48 Dep.listen(tag, function (text) { 49 el.innerHTML = text; 50 }) 51 }; 52 53 var dataObj = {}; //資料 54 function myFunction() { 55 setInterval(() => { 56 dataObj.one++; 57 },1000) 58 } 59 myFunction(); 60 //資料劫持 61 dataHijack({ 62 data: dataObj, 63 tag: 'view-1', 64 datakey: 'one', 65 selector: '.box-1' 66 }); 67 dataHijack({ 68 data: dataObj, 69 tag: 'view-2', 70 datakey: 'two', 71 selector: '.box-2' 72 }); 73 </script> 74 </body> 75 </html>