Vue元件之間通訊的三種方式

Kaiser_Lee發表於2018-09-28

最近在看樑顛編著的《Vue.js實戰》一書,感覺頗有收穫,特此記錄一些比價實用的技巧。

元件是MVVM框架的核心設計思想,將各功能點元件化更利於我們在專案中複用,這類似於我們服務端物件導向三大特性之一的封裝,將複雜的會被多次呼叫的程式碼封裝成元件,在需要呼叫的地方註冊使用即可。這樣設計的前端程式碼方便移植,可以跨專案複用。

元件之間的關係分為父子元件兄弟元件和跨多級元件等等,在元件之間互動資料,進行通訊主要通過三種方式來進行:

  1. 中央事件匯流排(非父子元件通訊)
  2. 父鏈
  3. 子元件索引

下面讓我們來好好說道說道這三種通訊方式:

一.中央事件匯流排

  這個東西名字叫的很唬人,但實際卻是很好理解的一種通訊方式,話不多說,我們來上程式碼。

  

<body>
    <div id="app">
        {{message}}
        <tempcomponent-a></tempcomponent-a>
    </div>
    <script>
        var middleware = new Vue();

        Vue.component(`tempcomponent-a`, {
            template: `<button @click="handleEvent">傳遞事件</button>`,
            methods: {
                handleEvent: function () {
                    middleware.$emit(`on-message`, `來自元件tempcomponent-a的內容`);
                }
            }
        });
        var app = new Vue({
            el: `#app`,
            data: {
                message: ``
            },
            mounted: function () {
                var _this = this;
                middleware.$on(`on-message`, function (msg) {
                    _this.message = msg;
                })
            },
        });
    </script>
</body>

在上面的程式碼中,空的Vue例項”middleware”就是我們的所謂的中央事件匯流排,我們可以看到,它負責在自元件”tempcomponent-a”中發出事件,在我們的主體Vue例項app中,通過監聽”middleware”來獲取子元件發出的內容。我的理解是中央事件匯流排就類似我們做交換資料的時候的臨時變數一樣,它在中間負責處理結果,然後返回訊息給請求者,它的職責就是中介。這個空的vue例項也可以加入data,methods等選項,這些都是可以作為公用的。

二.父鏈$parent

父鏈這個詞就很好理解啦,顧名思義即是元件的父物件,在元件內部可以直接通過$parent對父物件進行操作

<body>
    <div id="app">
        {{message}}
        <tempcomponent-a></tempcomponent-a>
    </div>
    <script>
        Vue.component(`tempcomponent-a`, {
            template: `<button @click="handleEvent">通過父鏈直接修改資料</button>`,
            methods: {
                handleEvent: function () {
                    this.$parent.message = `來自元件tempcomponent-a的訊息`;
                }
            }
        });
        var app = new Vue({
            el: `#app`,
            data: {
                message: ``
            }
        })
    </script>
</body>

通過上面的程式碼,我們可以看到在自元件內,使用父鏈$parent直接對父物件對屬性操作是非常簡單的。

三.子元件索引ref&$refs

子元件這個也很好理解,是在父物件上對所擁有對子元件進行操作,一般來說父容器內對子元件會有多個,所以每個元件需要設定特殊屬性ref來為自身指定一個唯一名稱。

<body>
    <div id="app">
        <button @click="handleRef">通過ref獲取子元件例項</button>
        <tempcomponent-a ref="comA"></tempcomponent-a>
    </div>
    <script>
        Vue.component(`tempcomponent-a`, {
            template: `<div>子元件</div>`,
            data: function () {
                return {
                    message: `子元件內容`
                }
            }
        });
        var app = new Vue({
            el: `#app`,
            methods: {
                handleRef: function () {
                    var msg = this.$refs.comA.message;
                    console.log(msg);
                }
            }
        })
    </script>
</body>

從程式碼可以看出,當我們直接在元件上建立ref屬性,在父物件中想對子元件進行操作,直接通過$refs.加上該元件唯一對ref屬性即可訪問。注意$refs是子元件渲染完成之後才填充對,而且不是響應式,應避免在計算屬性和模版中使用$refs

相關文章