js 简单的观察者模式实现

/* 观察者模式的简易实现,通过订阅data值的改变,执行callback */
let bindData = function (params) {
  onChange(this, params)
}

function onChange (vm, params) {
  // 定义不可被赋值运算符修改的属性eventHandle,防止对其类型进行破坏
  Object.defineProperty(vm, 'eventHandle', {
    value: {},
    writable: false
  })
  Object.keys(params).forEach((key) => {
    define.call(vm, key, params[key])
  })
}

function define (prototype, value) {
  Object.defineProperty(this, prototype, {
    // 通过set方法监听data的改变
    set: function (newValue) {
      // 从事件列表中获取到当前data的事件组
      let callbacks = this.eventHandle[prototype]
      // 循环调用当前事件组的callback
      for (let eventName in callbacks) {
        let callback = callbacks[eventName]
        if (typeof callback == 'function') {
          callback(newValue)
        }
      }
      value = newValue
    },
    get () {
      return value
    }
  })
}

bindData.prototype = {
  // 监听data的改变,
  // dataName: string / data的变量名
  // eventName: string / 事件的别名
  // callback:function / 需要在data发生改变时执行的callback
  onDataChange: function (dataName, eventName, callback) {
    let dataCallbacks = this.eventHandle[dataName] || {}
    if (typeof callback == 'function') {
      dataCallbacks[eventName] = callback
      this.eventHandle[dataName] = dataCallbacks
    }
  },

  // 取消监听,若只传dataName,将取消该变量的所有监听
  removeDataChange: function (dataName, eventName) {
    if (dataName, eventName) {
      let dataCallbacks = this.eventHandle[dataName] || {}
      delete dataCallbacks[eventName]
      this.eventHandle[dataName] = dataCallbacks
    } else if (dataName) {
      delete this.eventHandle[dataName]
    }
  }
}

export default new bindData({
  /* 在此处定义需要监听的data */
  test: {},
  testArr: []
})

/* 
  示例:

  import BindData from ./bindData

  BindData.onDataChange('test', 'testName', (res) => {
    console.log('test:', res)
  })

  BindData.onDataChange('test', 'testName2', (res) => {
    console.log('test2:', res)
  })

  BindData.test = {a: 1}

  输出: 
  test: {a: 1}
  test2: {a: 1}
*/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值