vue响应式原理——发布订阅,数据劫持

订阅器模型

// 订阅器模型
const Dep = {
  clientList: {},
  // 订阅
  listen(key, fn) {
    (this.clientList[key] ??= []).push(fn)
  },
  // 发布
  trigger() {
    const key = Array.prototype.shift.call(arguments)
    const fns = this.clientList[key]
    if (!fns || fns.length === 0) return
    for (let i = 0, fn; fn = fns[i++];) {
      fn.apply(this, arguments)
    }
  }
}

Object.defineProperty 数据劫持

/**
* 数据劫持
* @param {object} val 传递的对象
* @param {object} val.data 被劫持的对象
* @param {string} val.tag 唯一的key
* @param {string} val.datakey 被监听对象的属性
* @param {string} val.selector 获取dom元素的选择器
*/
const dataHi = ({
  data,
  tag,
  datakey,
  selector
}) => {
  let value = ''
  const el = document.querySelector(selector)
  // 订阅
  Dep.listen(tag, (text) => {
    el.innerHTML = text
  })

  Object.defineProperty(data, datakey, {
    get() {
      console.log('取值')
      return value
    },
    set(val) {
      console.log('写值')
      value = val
      // 发布
      Dep.trigger(tag, val)
    }
  })
}

使用

  • 然后改变 data.one 的值就可以对应的改变 dom 元素
const obj = {}

dataHi({
  data: obj,
  tag: 'view-1',
  datakey: 'one',
  selector: '.box-1'
})
posted @   懒惰ing  阅读(58)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示