vue組件詳解(三)——組件通信

来源:https://www.cnblogs.com/chaixiaozhi/archive/2018/04/08/8746823.html
-Advertisement-
Play Games

組件之間通信可以用下圖表示: 組件關係可分為父子組件通信、兄弟組件通信、跨級組件通信。 一、自定義事件 當子組件需要向父組件傳遞數據時,就要用到自定義事件。 子組件用$emit ()來觸發事件,父組件用$on()來監昕子組件的事件。 父組件可以直接在子組件的自定義標簽上使用v-on 來監昕子組件觸發 ...


組件之間通信可以用下圖表示:

組件關係可分為父子組件通信、兄弟組件通信、跨級組件通信。

一、自定義事件

當子組件需要向父組件傳遞數據時,就要用到自定義事件。

子組件用$emit ()來觸發事件,父組件用$on()來監昕子組件的事件。

父組件可以直接在子組件的自定義標簽上使用v-on 來監昕子組件觸發的自定義事件,如:

        <div id="app9">
            <p>總數:{{total}}</p>
            <my-component9 @add="getTotal" @cut="getTotal"></my-component9>
        </div>
Vue.component('my-component9',{
    template: '<div>' +
    '               <button @click="increase">+1</button>' +
    '               <button @click="reduce">-1</button>' +
            '</div>',
    data: function(){
        return {
            count: 0
        }
    },
    methods:{
        increase: function(){
            this.count++;
            this.$emit('add',this.count)  //廣播的事件名和數據
        },
        reduce: function(){
            this.count--;
            this.$emit('cut',this.count)  //廣播的事件名和數據
        }
    }
});

var app9 = new Vue({
    el: '#app9',
    data:{
        total: 0
    },
    methods:{
        getTotal: function(count){
            this.total = count;
        }
    }
});

 

二、使用v-model

Vue2 .x 可以在自定義組件上使用v-model 指令,直接看一個事例:

        <div id="app10">
            <p>總數:{{total}}</p>
            <my-component10 v-model="total"></my-component10>  //這個地方v-model實際是一個語法糖,可以直接理解為接收到廣播input裡面的數據(this.total=count)。
        </div>
Vue.component('my-component10',{
    template: '<div>' +
                '<button @click="increase">+1</button>' +
                '<button @click="reduce">-1</button>' +
              '</div>',
    data: function(){
        return {
            count: 0
        }
    },
    methods:{
        increase: function(){
            this.count++;
            this.$emit('input',this.count)  //註意這個地方,廣播的事件名稱為特殊的input
        },
        reduce: function(){
            this.count--;
            this.$emit('input',this.count)  //註意這個地方,廣播的事件名稱為特殊的input
        }
    }
});

var app10 = new Vue({
    el: '#app10',
    data:{
        total: 0
    }
});

 

 v-model 還可以用來創建自定義的表單輸入組件, 進行數據雙向綁定,例如:

        <div id="app11">
            <p>總數:{{total}}</p>
            <my-component11 v-model="total"></my-component11>
            <button @click="reduce">-1</button>
        </div>
Vue.component('my-component11', {
    props: ['value'],  //使用v-model的表單組件時,父組件通過value來進行傳值
    template: '<input :value="value" @input="updateValue">',
    methods: {
        updateValue: function(event){
            this.$emit('input', event.target.value);
        }
    }
});

var app11 = new Vue({
   el: '#app11',
   data:{
      total: 0
    },
    methods:{
        reduce: function(){
            this.total--
        }
    }
});

 

父組件的total發生變化時,會通過傳遞value值,影響子組件input中的value值,而子組件改變自己input中的value值,又會廣播給父組件,影響父組件中的total值。

實現這樣一個具有雙向綁定的v -model 組件要滿足下麵兩個要求:

•接收一個value 屬性。
• 在有新的value 時觸發input 事件。

 

三、非父子組件通信

在Vue . 2.x 中, 推薦使用一個空的Vue 實例作為中央事件匯流排( bu s ),也就是一個中介。

直接看一個事例:

        <div id="app12">
            <p>{{message}}</p>
            <my-component12></my-component12>
        </div>
var bus = new Vue();

Vue.component('my-component12',{
   template: '<button @click="updateMessage">傳遞事件信息</button>',
    methods: {
        updateMessage: function(){
            bus.$emit('updateMessage','更新我的組件信息');   //利用中介bus傳播事件
        }
    }
});

var app12 = new Vue({
   el: '#app12',
   data:{
        message: ''
    },
    mounted: function(){
        var _this = this;   //這一步賦值必須有
        bus.$on('updateMessage',function(data){     //利用中介bus接收事件
            _this.message = data;
        })
    }
});

在app 初始化時,也就是在生命周期mounted 鉤子函數里監聽了來自bus 的事件updateMessage(mounted掛載這一步相當於在兩個組件直間提前安排了一個中介,當兩個組件通信時,就可以通過該中介相互傳遞消息了) ,

而在組件my-component12中,點擊按鈕會通過bus 把事件updateMessage發出去,此時app 就會接收到來自bus 的事件,進而在回調里完成自己的業務邏輯。

這種方法巧妙而輕量地實現了任何組件間的通信,包括父子、兄弟、跨級,而且Vue 1.x 和Vue 2.x 都適用。

 

四、父鏈與子組件索引

除了中央事件匯流排bus 外,還有兩種方法可以實現組件間通信:父鏈和子組件索引。

在子組件中,使用this.$parent 可以直接訪問該組件的父實例或組件,父組件也可以通過this.$children 訪問它所有的子組件,而且可以遞歸向上或向下無線訪問, 直到根實例或最內層的組件。

4.1父鏈

        <div id="app13">
            <p>{{message}}</p>
            <my-component13></my-component13>
        </div>
Vue.component('my-component13',{
    template: '<button @click="updateMessage">通過父鏈直接修改數據</button>',
    methods: {
        updateMessage: function(){
            this.$parent.message = '來自組件my-component13的內容'  //通過this.$parent直接修改父組件的內容
        }
    }
});

var app13 = new Vue({
    el: '#app13',
    data:{
        message: ''
    }
});

 儘管V ue 允許這樣操作,但在業務中, 子組件應該儘可能地避免依賴父組件的數據,更不應該去主動修改它的數據,因為這樣使得父子組件緊藕合,理想情況下,只有組件自己能修改它的狀態。


4.2 子組件索引

當子組件較多時, 通過this.$children 來一一遍歷出我們需要的一個組件實例是比較困難的,尤其是組件動態渲染時,它們的序列是不固定的。Vue 提供了子組件索引的方法,用特殊的屬性ref來為子組件指定一個索引名稱。

        <div id="app14">
            <p>{{message}}</p>
            <my-component14 ref="com14"></my-component14>
            <button @click="handleRef">通過ref獲取子組件實例</button>
        </div>
Vue.component('my-component14',{
    template: '<div>子組件</div>',
    data: function(){
        return {
            message: '子組件內容'
        }
    }
});

var app14 = new Vue({
    el: '#app14',
    data:{
        message: ''
    },
    methods: {
        handleRef: function(){
             this.message = this.$refs.com14.message;   //通過$refs獲取子組件實例
        }
    }
});

 在父組件模板中,子組件標簽上使用ref 指定一個名稱,井在父組件內通過this.$refs 來訪問指定名稱的子組件。

$refs 只在組件渲染完成後才填充,並且它是非響應式的. 它僅僅作為一個直接訪問子組件的應急方案,應當儘量避免在模板或計算屬性中使用$refs。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在實現一個問題的時候,同樣的結果我寫了兩個sql。 sql1 sql2 在效率問題上詢問了前輩,得到的建議是使用第二個,因為分組跟子查詢都會影響效率,相比之下分組好一點。 另外產生的一個問題是,如果使用.net並使用c#語言實現sql的話,第一個sql是無法(在我的能力範圍內)使用拉姆達查詢對象的, ...
  • 資料庫的三大特性可謂是:實體屬性和關係。 實體:表; 屬性:表中的數據(欄位); 關係:表與表之間的關係。 資料庫設計三大範式(重點): 第一範式(1NF):數據表中的每一列(每個欄位)必須是不可拆分的最小單元,也就是確保每一列的原子性; 第二範式(2NF):滿足1NF後,要求表中的所有列,都必須依 ...
  • 一、用Log列印日誌 二、Toast用法 三、在活動中使用Menu 首先在res目錄下新建menu文件夾,接著在這個文件夾下新建一個名叫main的菜單文件,在main.xml中添加如下代碼 回到Activity中重寫onCreateOptionsMenu()方法,編寫如下代碼(返回true表示允許創 ...
  • 一、view鉤子 view鉤子有2個,ngAfterViewInit和ngAfterViewChecked鉤子。 1、實現ngAfterViewInit和ngAfterViewChecked鉤子時註意事項 以父組件調用子組件方法 中例子為基礎,在父組件中實現ngAfterViewInit和ngAft ...
  • 一、什麼是slot 在使用組件時,我們常常要像這樣組合它們: 當需要讓組件組合使用,混合父組件的內容與子組件的模板時,就會用到slot , 這個過程叫作內容分發( transclusion )。 註意兩點: 1.< app>組件不知道它的掛載點會有什麼內容。掛載點的內容是由<app >的父組件決定的 ...
  • 原型與原型鏈是學習JavaScript這門語言不能不理解的兩個重要概念,為什麼?因為JavaScript是一門基於原型的語言。 怎麼理解“JavaScript是一門基於原型的語言”?在軟體設計模式中,有一種模式叫做原型模式,JavaScript正是利用這種模式而被創建出來。先來瞭解下原型模式的概念... ...
  • 自己跟著網上教程複習上學期的HTML+CSS,因為已經忘得差不多了,而且現在學的js也要以HTML+CSS為基礎,堅持每天持續更新。 n B/S 網路結構 Browser/Server 瀏覽器/伺服器,這是現在最流行的網路模式。如新浪網、鳳凰網等。 C/S Client/Server 客戶端/伺服器 ...
  • 昨天編輯朋友圈文章,無法修改提交的bug終於找到了,原因是用錯了一個標點... 把req點body寫成req逗號body,印象深刻,發人深省。 編輯後,終於可以修改成功了。 雖然只是一個小小的bug,,但是印象實在太過深刻。 所以說寫代碼的時候不用心,改bug的時候就耽誤一天。 晚上還嘗試做了一個刪 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...