1. 程式人生 > 程式設計 >Vue釋出訂閱模式實現過程圖解

Vue釋出訂閱模式實現過程圖解

vue專案中不同元件間通訊一般使用vuex,通常情況下vuex和EventBus不應該混用,不過某些場景下不同元件間只有訊息的互動,這時使用EventBus訊息通知的方式就更合適一些。

圖解

Vue釋出訂閱模式實現過程圖解

Vue釋出訂閱模式實現過程圖解

html

<body>
 <script src="./Dvue.js"></script>
 <script>
  const app = new DVue({
   data: {
    test: "I am test",foo: {
     bar: "bar"
    }
   }
  })

  app.$data.test = "hello world!"
  // app.$data.foo.bar = "hello!"
 </script>
</body>

Dvue.js

class DVue {
 constructor(options) {
  this.$options = options

  // 資料響應化
  this.$data = options.data
  this.observe(this.$data)

  // 模擬一下watcher建立
  // 啟用get 並將依賴新增到deps陣列上
  new Watcher()
  this.$data.test
  new Watcher()
  this.$data.foo.bar
 }

 observe(value) {
  // 判斷value是否是物件  
  if (!value || typeof value !== 'object') {
   return
  }
  
  // 遍歷該物件
  Object.keys(value).forEach(key => {
   this.defineReactive(value,key,value[key])
  })
 }

 // 資料響應化
 defineReactive(obj,val) {
  // 判斷val內是否還可以繼續呼叫(是否還有物件)
  this.observe(val) // 遞迴解決資料巢狀

  // 初始化dep
  const dep = new Dep()

  Object.defineProperty(obj,{
   get() {
    // 讀取的時候 判斷Dep.target是否有,如果有則呼叫addDep方法將Dep.target新增到deps陣列上
    Dep.target && dep.addDep(Dep.target)
    return val
   },set(newVal) {
    if (newVal === val) {
     return;
    }
    val = newVal
    // console.log(`${key}屬性更新了:${val}`)
    dep.notify() // 更新時候呼叫該方法
   }
  })
 }
}


// Dep: 用來管理Watcher
class Dep {
 constructor() {
  // 這裡存放若干依賴(watcher) |一個watcher對應一個屬性
  this.deps = [];
 }

 // 新增依賴
 addDep (dep) {
  this.deps.push(dep)
 }

 // 通知方法
 notify() {
  this.deps.forEach(dep => dep.update())
 }
}

// Watcher
class Watcher {
 constructor () {
  // 將當前watcher例項指定到Dep靜態屬性target上
  Dep.target = this  // 當前this就是Watcher物件
 }

 update() {
  console.log('屬性更新了')
 }
}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。