vue 响应式模拟

观察者模式

  1. 观察者模式包含 subject(观察目标) 和 watcher(观察者) 两类对象。一个 subject 通常对应着多个 watcher,subject 的状态发生变化,所有 watcher 都会收到通知。
  2. 观察者是知道 subject 的,subject 一直保持对观察者进行记录。(而发布订阅模式的发布者和订阅者不知道对方的存在,它们只有通过消息代理进行通信。)
  3. 观察者模式大多数时候是同步的,而发布-订阅模式大多数时候是异步的

代码

可以直接运行调试

let data

let active
let onChanged = (cb) => {
  // 把响应回调的函数临时存在 active
  active = cb
  // 首次主动调用回调函数
  active()
  // 调用后将其置为 null,以免重复依赖
  active = null
}

class Dep {
  deps = new Set()

  depend() {
    if (active) {
      // 添加观察者
      this.deps.add(active)
    }
  }

  notify() {
    // 通知所有观察者
    this.deps.forEach((dep) => dep())
  }
}

let ref = (initValue) => {
  let value = initValue
  // 每个变量独享一个 dep 对象
  let dep = new Dep()

  return Object.defineProperty({}, 'value', {
    get() {
      // 读取是添加观察者
      dep.depend()
      return value
    },
    set(newVal) {
      value = newVal
      // 写入后通知所有观察者
      dep.notify()
    },
  })
}

// reactive
data = ref(1)

// dom
const iptEl = document.querySelector('#ipt')
const resultEl = document.querySelector('#result')

iptEl.addEventListener('input', (e) => {
  data.value = e.target.value
})

onChanged(() => {
  resultEl.innerHTML = data.value
})
<!DOCTYPE html>
<html lang="zh-cn">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vue Reactive</title>
     <style>
      .container {
        margin: 100px auto;
        width: 500px;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <label for="ipt">input</label>
      <input type="text" id="ipt" value="1" />
      <br />
      <br />
      <label for="result">value</label>
      <span id="result"></span>
    </div>
    <script src="./index.js"></script>
  </body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值