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
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...