发布者订阅者模式(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>