從vue的組件傳值着手淺談觀察者模式 vue項目使用websocket技術

 

 

 

 

首先,提到觀察者模式,這不由讓我想到了MVVM,MVVM架構模式感受用到了觀察者的思想。html

咱們仍是按照慣例,瞭解一下什麼是觀察者模式vue

 

觀察者模式,相似發佈訂閱模式,完成這個動做首先最少得有兩個不一樣的對象,或者多個對象,他更像是一種一隊多的依賴關係,也就是一種對象的狀態發生改變,與其相關全部的對象的狀態都會發生改變;好比說朋友圈這個功能,一我的可能有上百個好友,當我發佈一條朋友圈後,全部和我成爲好友的人都會看見這個朋友圈,當另外一我的點贊後,全部你的好友其餘點讚的人也會收到通知,這很像觀察者,也就是我是發佈者,個人好友是訂閱者。node

而後咱們看一下什麼是vue,vue的原理你們都知道,他是一種自底向上的一種深刻響應式的雙向綁定模式,即MVVM,也就是說,vue關注model的變化,model的變化讓mvvm框架更新dom,從而產生視圖view變化。web

舉一個項目中很常見的例子:vuex

在寫vue項目中咱們都用過父子組件傳值,可是兄弟組件傳值是怎麼實現的,首先咱們能夠用vuex,這很常見,可是還有一種方法不知道你用過沒有,就是Bus,這個Bus只是一種命名而已,叫什麼無所謂,你能夠叫飛機大炮均可以,這不重要,咱們主要看看他是怎麼實現的:api

第一步,咱們先在main.js中註冊一下bus:websocket

Vue.prototype.$Bus = new Vue()

 

咱們往vue的原型裏註冊了一個全局變量$Bus,他的值是vue的實例,也就是說,到如今爲止,$Bus裏邊有了vue全部的屬性和方法,這下就好操做了架構

第二步,咱們開始發送消息,這就很符合觀察者模式的發佈訂閱模式框架

咱們在組件1中寫以下代碼:dom

<template>
    <div>
        <button @click="send">發送</button>
    </div>
</template>

<script>
export default {
    methods: {
        send () {
            this.$Bus.$emit("send",'接收的信息')
        }
    }
}
</script>

 

點擊按鈕發送一條信息,這個按鈕也就是充當發佈者,咱們用到了vue的$emit這個api,那麼訂閱者是什麼呢?我不說你也應該想到了,對,就是他

第三步,在組件三中接收消息

<template>
    <div>
        {{message}}
    </div>
</template>

<script>
export default {
    data () {
        return {
            message: ''
        }
    },
    mounted () {
        this.$Bus.$on('send', (msg) => {
            this.message = msg
        })
    }
}
</script>

 

就是用$on這個屬性充當接收者

從上能夠看出,vue不少地方用到了觀察者的思想,包括他的雙向綁定也是如此,首先咱們看看vue的機制:

 

 從上圖咱們能夠看出,vue是經過Object.defineProperty實現對數據的劫持,而後中間作了一箇中轉,最後渲染到vue層。

咱們能夠確定的是,vue.js借鑑了觀察者模式,可是我感受仍是有點區別的,觀察者模式跟注重的是事件驅動,好比我買房這個動做,第一次和銷售瞭解可能沒有合適的房源,而後銷售就會跟你說: ‘若是有合適的房源咱們會第一時間通知你’,當有新房源的時候他會給你打電話通知你,這一系列的根源是買房這個事件,他驅動了整套流程。而vue咱們都知道是數據驅動,也就是隻有data裏的值發生改變的話,Object.defineProperty纔會對他劫持,從而去更新dom,觸發視圖的更新。

 

那麼有沒有更符合觀察者模式特徵的?

固然是node.js的events事件了。

首先咱們看看events的工做流程:

var events = require('events');
// 建立 eventEmitter 對象
var eventEmitter = new events.EventEmitter();
// 建立事件處理程序
var connectHandler = function connected() {
   console.log('鏈接成功。');
   // 觸發 data_received 事件 
   eventEmitter.emit('data_received');
}
// 綁定 connection 事件處理程序
eventEmitter.on('connection', connectHandler);
// 使用匿名函數綁定 data_received 事件
eventEmitter.on('data_received', function(){
   console.log('數據接收成功。');
});
// 觸發 connection 事件 
eventEmitter.emit('connection');
console.log("程序執行完畢。");

輸出一下:

 

這就徹底符合觀察者的工做模式,由emit發佈,由on接收。因此說,node.js提供了很好的監聽機制,還有他對整個事務的處理 。其支持了nodejs最特點的I/O模式,好比咱們啓動http服務時會監聽其 connect / close,http.request時會監聽 data / end等。

 

還有沒有相似的案例呢?

固然,js有一個事件監聽者----addEventListener,也有點觀察者的意思,具體用法我就不說了,想必你們用的都很熟悉。

其實只要你認真想想,仍是有不少地方有觀察者的身影的,最簡單的就是一個點擊事件,是否是也有其意思,發佈者是一個按鈕,而接收者能夠是表單,彈層等任何東西。

 

那麼,對於觀察者模式存在的意義有哪些呢?

首先咱們說說他的優勢:

1,觀察者模式須要在觀察者和被觀察者之間創建一個耦合,他須要一個更加抽象化將兩者聯繫在一塊兒

2,觀察者模式支持廣播,也就是一對多的關係,這就讓咱們很容易想到一個技術,就是socket,具體能夠參考vue項目使用websocket技術

然鵝,他也是優缺點的:

1,建立訂閱者自己要消耗必定的時間和內存

2,當訂閱一個消息時,也許此消息並無發生,但這個訂閱者會始終存在內存中。

3,觀察者模式弱化了對象之間的聯繫,這本是好事情,但若是過分使用,對象與對象之間的聯繫也會被隱藏的很深,會致使項目的難以跟蹤維護和理解。

 

等會兒,還有一個模式叫發佈訂閱模式,不少人都覺得他就是觀察者模式(包括我),後來我上網查了一下,發現他們仍是有區別的,咱們能夠說觀察者模式和發佈訂閱模式很像,真的很像,可是本質仍是有點區別的,最根本的就是調度中心不一樣。

舉個例子,觀察者模式更注重是目標和觀察者是抽象類,好比天氣預報,觀察者A負責監聽天氣的變化,而B想得知天氣的變化須要將本身註冊到A中,而天氣變化的時候A觸發天氣變化,調度B的接口更新變化。

而發佈訂閱模式是如何完成這個動做的呢?A想要感知天氣變化,須要B這個調度中心,而B獲得天氣變化須要依賴C的觸發,可能我解釋的不是很清楚,網上有兩個圖比較好,我粘到下面,提供參考(侵權必刪哈哈哈)

 

 

 

 

 

 

 

好了,對於觀察者模式個人理解就到這裏,歡迎指正!

相關文章
相關標籤/搜索