1. 程式人生 > >看了就懂的vue元件通訊

看了就懂的vue元件通訊

本文在具體實現上,主要是基於vue2.0並使用vue-cli腳手架搭建的一個基本專案,至於vue-cli這個腳手架,如果不懂也沒關係,可以先用  ̄□ ̄||,主要介紹的是元件之間的通訊。

0、前置

首先,肯定要有安裝node和vue-cli了,具體怎麼安裝就不介紹了。

然後,建立一個初始化的專案vue_demo_2: vue init webpack vue_demo
這裡寫圖片描述
生成的專案結構如下:
這裡寫圖片描述
專案結構介紹:

| - build (執行資料夾,dev/prod執行時需要用到的相關檔案,含webpack配置)
| - config (配置資料夾,比如說dev/prod兩種對應的不同介面等設定)
| - dist (打包生成的部署資料夾,一開始沒有的,跑命令npm run build之後可見!!!) | - node_modules (一些安裝的依賴模組) | - src (專案程式碼)   | - assets (資原始檔夾,為了區分static,這裡存自己的資源)   | - components (頁面資料夾,用來存放一些元件)   | - router (路由資料夾)   | - App.vue (vue主檔案)   | - main.js (入口檔案,webpack配置的entrance) | - static (資原始檔夾,為了區分assets,這裡存第三方的資源) | - .babelrc (轉碼規則配置)
| - .editorconfig (程式碼規範配置) | - .eslintignore (eslint檢查忽略配置) | - .eslintrc.js (eslint配置檔案) | - .gitignore (git忽略配置) | - .postcssrc.js (postcss的load的config,檔案裡有對應的github地址) | - index.html (html主頁面) | - package.json (專案的一些基本介紹,比如專案的描述、用到哪些模組等) | - README.md

接下來,就可以正常實現不同元件之間的資料傳遞了,即元件之間的通訊。

1、父元件向子元件傳遞資料

將App.vue這個元件中刪除原來模板中的東西只保留基本的框架,當前App.vue檔案內容如下:

<template>
  <div id="app">

  </div>
</template>

<script>
export default {
  name: 'App'
}
</script>

<style></style>

src/components資料夾下,新建一個Child.vue單檔案元件,建立props用於接收資料,幷包含一個message屬性,內容結構如下:

<template>
  <div class="child">
      <h2>我是子元件</h2>
      <p>這是我從父元件接收到的資料: {{cMessage}}</p>
  </div>
</template>

<script>
export default {
  name: 'Child',
  props:["cMessage"]
}
</script>

<style>
  .child{
    border:1px solid blue;
    width: 50%;
  }
</style>

App.vue元件,相當於是父元件中,引入子元件檔案,並呼叫該子元件,然後將資料傳遞給子元件,修改後App.vue程式碼如下:

<template>
  <div id="app">
    <h1>我是父元件</h1>
    <child cMessage="hello child"></child> <!-- 呼叫子元件, 注意cMessage這個屬性名稱是由子元件中props定義 -->
  </div>
</template>

<script>
import Child from './components/Child.vue' // 引入子元件檔案
export default {
  name: 'App',
  components:{
    Child // 宣告子元件
  }
}
</script>

<style>
#app{
  width: 60%;
  border: 1px solid red;
}
</style>

npm run dev 在瀏覽器開啟之後我們可以看到,父元件已經把資料傳遞給子元件了。
這裡寫圖片描述
這是父元件向子元件傳遞的靜態資料,當動態傳遞資料時,需要用到v-bind繫結資料,修改App.vue檔案程式碼如下:

<template>
  <div id="app">
    <h1>我是父元件</h1>
    <!-- <child cMessage="hello child"></child> 呼叫子元件 -->
    <child v-bind:cMessage="pMessage"></child> <!-- 動態繫結父元件資料 ,cMessage還是子元件中props中的屬性,pMessage是父元件的資料 -->
  </div>
</template>

<script>
import Child from './components/Child.vue' // 引入子元件檔案
export default {
  name: 'App',
  components:{
    Child // 宣告子元件
  },
  data(){
    return {
      pMessage:'hello child , 這是動態資料'
    }
  }
}
</script>

<style>
#app{
  width: 60%;
  border: 1px solid red;
}
</style>

結果如下:
這裡寫圖片描述
以上就完全實現了父元件向子元件的通訊了,總結:

第一步: 子元件在props中建立屬性,用於接收父元件傳遞來的資料;

第二步:父元件先引入子元件檔案,宣告子元件,然後呼叫子元件,並在呼叫的子元件時,引用子元件props中宣告的屬性,將父元件資料賦值給該屬性,就實現了父向子元件的資料傳遞,動態資料則是通過v-bind繫結父元件資料。

2、子元件向父元件傳遞資料

接著,繼續實現子元件向父元件通訊,修改Child.vue子元件檔案,新增一個button 並給該按鈕綁定了一個點選事件,在該點選事件方法中使用$emit()方法將資料傳遞給父元件,具體程式碼內容如下:

<template>
  <div class="child">
      <h2>我是子元件</h2>
      <p>這是我從父元件接收到的資料: {{cMessage}}</p>
      <button v-on:click="sendMessage">傳資料給父元件</button>
  </div>
</template>

<script>
export default {
  name: 'Child',
  props:["cMessage"],
  methods:{
    sendMessage(){
      // 第一個引數:子元件觸發的一個自定義事件, 第二個引數:子元件要向父元件傳遞的資料
      this.$emit('childEvent','hello parent , 這是從子元件傳來的資料');
    }
  }
}
</script>

<style>
  .child{
    border:1px solid blue;
    width: 50%;
  }
</style>

App.vue這個父元件檔案中,同樣呼叫子元件,同時利用v-on監聽子元件自定義的事件,並繫結自己本身實現的方法,具體程式碼修改內容如下:

<template>
  <div id="app">
    <h1>我是父元件</h1>
    <!-- <child message="hello child"></child> 呼叫子元件 -->
    <!-- <child v-bind:cMessage="pMessage"></child> 動態繫結父元件資料 -->
    <p>這是我從子元件接收到的資料:{{fromChild}}</p>
    <!-- 父元件觸發的childEvent是子元件中方法sendMessage中$emit()的第一個引數自定義的事件名稱,showMessage是父元件methods中的方法 -->
    <child v-bind:cMessage="pMessage" v-on:childEvent="showMessage"></child> 
  </div>
</template>

<script>
import Child from './components/Child' // 引入子元件檔案
export default {
  name: 'App',
  components:{
    Child // 宣告子元件
  },
  data(){
    return {
      pMessage:'hello child , 這是動態資料',
      fromChild:''
    }
  },
  methods:{
    showMessage(data){
      this.fromChild = data;
    }
  }
}
</script>

<style>
#app{
  width: 60%;
  border: 1px solid red;
}
</style>

在瀏覽器中,點選資料傳遞按鈕,可以看到:
這裡寫圖片描述
這樣,也實現了子元件向父元件的資料傳遞,總結:

第一步: 子元件需要用$emit()觸發一個自定義事件,事件名稱即第一個引數名稱,並將要傳給父元件的資料作為$emit()的第二個引數。

第二步: 父元件同樣需要引用子元件檔案,宣告子元件,然後呼叫子元件,在呼叫子元件時需要用v-on監聽子元件中自定義的事件,繫結自身的方法,而該方法的引數就是子元件傳遞過來給父元件的資料。

3、元件之間的資料傳遞

在vue中,很多的一種情況就是元件之間並沒有父子關係,就是很普通的兩個元件,那麼這種平級元件之間的通訊是怎麼的,在理解父子元件之間通訊的基礎上,我們接下來繼續介紹它們的實現。

src/assets檔案加下,新建一個mEvent.js檔案,該js檔案程式碼如下:

import Vue from 'vue'

export default new Vue

可以看到mEvent.js裡面放的是一個空的Vue例項物件,事實上,通過父子元件之間相互通訊父元件向子元件傳遞資料是藉助porps,子元件向父元件通訊則是藉助$emit(),可以發現都需要一箇中介,而平級元件之間的通訊則是可以通過這個mEvent.js作為中介來實現。

src/componets資料夾下新建3個單檔案元件:FirstComponent.vueSecondComponent.vueThirdComponent.vue,並在在App.vue這個元件中引用,此時App.vue中的程式碼為:

<template>
  <div id="app">
    <first-component></first-component>   <!-- 呼叫元件 -->
    <second-component></second-component>
    <third-component></third-component>
  </div>
</template>

<script>
import FirstComponent from './components/FirstComponent' // 引入單檔案元件
import SecondComponent from './components/SecondComponent'
import ThirdComponent from './components/ThirdComponent'

export default{
  name:'App',
  components:{
    FirstComponent, // 宣告元件
    SecondComponent,
    ThirdComponent
  }
}
</script>

<style>
#app{
  width: 80%;
  border: 1px solid black;
}
</style>

在第1個元件中,將資料傳遞給第3個元件,FirstComponent.vue具體程式碼如下:

<template>
    <div class="firstComponent">
        <h2>我是第1個元件</h2>
        <button v-on:click="oneSendToThird">向元件3傳遞資料</button>
    </div>
</template>

<script>
import mEvent from '../assets/mEvent.js' // 引入做問中介的單一事件
export default{
    name:'FirstComponent',
    methods:{
        oneSendToThird(){
            mEvent.$emit('firstComponentMessage','hello,這是來自第1個元件的資料');
        }
    }
}
</script>

<style>
.firstComponent{
    width: 60%;
    border: 1px solid red;
}
</style>

同樣,在第2個元件中也將資料傳遞給第3個元件,SecondComponent.vue具體實現如下:

<template>
    <div class="secondComponent">
        <h2>我是第2個元件</h2>
        <button v-on:click="twoSendToThird">向元件3傳遞資料</button>
    </div>
</template>

<script>
import mEvent from '../assets/mEvent.js' // 引入做問中介的單一事件
export default{
    name:'SecondComponent',
    methods:{
        twoSendToThird(){
            mEvent.$emit('secondComponentMessage','hi,這是來自第2個元件的資料');
        }
    }
}
</script>

<style>
.secondComponent{
    width: 60%;
    border: 1px solid green;
}
</style>

此時,第3個元件要接收來自第1和第2個元件傳遞過來的資料,ThirdComponent.vue具體實現如下:

<template>
    <div class="thirdComponent">
        <h2>我是第3個元件</h2>
        <p>這是從第1個元件發過來的資料:{{msg1}}</p>
        <p>這是從第2個元件發過來的資料:{{msg2}}</p>
    </div>
</template>

<script>
import mEvent from '../assets/mEvent.js' // 引入做問中介的單一事件
export default{
    name:'ThirdComponent',
    data(){
        return{
            msg1:'',
            msg2:''
        }
    },
    mounted() {
         /*要借用es6的箭頭函式,如果不用箭頭函式
            在觸發$on()事件前先:_this=this; 然後在普通函式中將資料賦值:_this.msg = data1;
            如果事先不暫存this,則會由於this的問題無法將資料新增
        */
        mEvent.$on('firstComponentMessage', (data1)=> {
            this.msg1 = data1;  
        })
         mEvent.$on('secondComponentMessage', (data2)=> {
            this.msg2 = data2;
        })
    },
}
</script>

<style>
.thirdComponent{
    width: 60%;
    border: 1px solid green;
}
</style>

那麼在瀏覽器,分別點選按鈕,可以看到資料已經傳送成功了。
這裡寫圖片描述
從程式碼實現來看,不難發現平級元件之間資料的通訊主要通過藉助一箇中介mEvent.js,其實就是一個空的Vue例項物件,然後在利用$emit()發資料,$on()接資料,所以總結一下就是:

第一步:建立一個單一的事件中心來管理元件之間的通訊,事實上就是一箇中介;

第二步:在需要傳值的元件中$emit()觸發一個自定義事件,並傳遞引數;

第三步:在需要接收資料的元件中$on()監聽自定義事件,並在回撥函式中處理傳遞過來的引數。

至此,父子元件之間和不同元件之間的通訊就已經完全實現了。

4、非vue-cli專案中元件之間的通訊示例

其實本文主要介紹的就是利用vue-cli搭建一個初始化專案,然後實現單檔案元件之間的通訊,但是考慮到有些情況下,可能並沒有用到vue-cli,所以還是決定實現一下非單檔案元件通訊實現的寫法。

4.1 父元件向子元件傳遞資料

在電腦任意資料夾下,新建一個componet_comunication1.html,然後用在該檔案中引入vue.js(2.0版本),實現父元件向子元件傳遞資料,具體程式碼如下:

<html>
    <head>
        <meta charset="utf-8">
        <title>父元件向子元件傳遞資料</title>
    </head>

    <style>
        #app{
            width: 50%;
            border: 1px solid red;
        }
        .child{
            width: 60%;
            border:1px solid blue;
        }
    </style>

    <body>

        <div id="app">
            <h2>我是父元件</h2>
            <child :msg="message"></child>
        </div>

        <template id="child">
            <div class="child">
                <h2>我是子元件</h2>
                <p>這是父元件傳遞過來的資料:{{msg}}</p>
            </div>
        </template>

    </body>

    <script src="https://cdn.bootcss.com/vue/2.5.17-beta.0/vue.js"></script> <!-- 單獨引入vue檔案 -->
    <script>
        window.onload = function () {
            new Vue({
                el:'#app',
                data:{
                    message:'hello child, 這是父元件的資料'
                },
                components:{ // 註冊一個子元件
                    'child':{
                        props:['msg'],
                        template:'#child'
                    }
                }
            })
        }
    </script>

</html>

結果展示:
這裡寫圖片描述
由於文章前面已經具體介紹過父元件如何向子元件傳遞資料的,所以就不再相信介紹了,只給出具體的實現demo。

4.2 平級元件之間資料傳遞

那麼,平級元件之間傳遞資料componet_comunication_2.html程式碼實現如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>平級元件資料通訊</title>
</head>

<body>
    <div id="box">
        <com-a></com-a>
        <com-b></com-b>
        <com-c></com-c>
    </div>
</body>

<script src="https://cdn.bootcss.com/vue/2.5.17-beta.0/vue.js"></script> 
<script>
    var Event=new Vue(); //準備一個空的例項物件
    var A={ // 元件A
        template:`
            <div>
                <span>我是A元件</span> -> {{a}}
                <input type="button" value="把A資料給C" @click="send">
            </div>
        `,
        methods:{
            send(){
                Event.$emit('a-msg',this.a);
            }
        },
        data(){
            return {
                a:'我是a資料'
            }
        }
    };
    var B={ // 元件B
        template:`
            <div>
                <span>我是B元件</span> -> {{a}}
                <input type="button" value="把B資料給C" @click="send">
            </div>
        `,
        methods:{
            send(){
                Event.$emit('b-msg',this.a);
            }
        },
        data(){
            return {
                a:'我是b資料'
            }
        }
    };
    var C={ // 元件C
        template:`
            <div>
                <h3>我是C元件</h3>
                <span>接收過來的A的資料為: {{a}}</span>
                <br>
                <span>接收過來的B的資料為: {{b}}</span>
            </div>
        `,
        data(){
            return {
                a:'',
                b:''
            }
        },
        mounted(){
            Event.$on('a-msg',function(a){  //接收A元件的資料
                this.a=a;
            }.bind(this));
            Event.$on('b-msg',function(a){  //接收B元件的資料
                this.b=a;
            }.bind(this));
        }
    };
    window.onload=function(){
        new Vue({
            el:'#box',
            components:{
                'com-a':A,
                'com-b':B,
                'com-c':C
            }
        });
    };
</script>
</html>

結果展示:
這裡寫圖片描述

好了,簡單易懂的vue元件通訊介紹就到這,後續有遇到的更多知識會慢慢補充的。如果不足或者不對的地方,歡迎各位指出~

每天總結一點點,每天進步一點點(^-^)V

相關推薦

vue元件通訊

本文在具體實現上,主要是基於vue2.0並使用vue-cli腳手架搭建的一個基本專案,至於vue-cli這個腳手架,如果不懂也沒關係,可以先用  ̄□ ̄||,主要介紹的是元件之間的通訊。 0、前置 首先,肯定要有安裝node和vue-cli了,具體怎麼安裝就不

深入理解學習Git工作流,

個人在學習git工作流的過程中,從原有的 SVN 模式很難完全理解git的協作模式,直到有一天我看到了下面的文章,好多遺留在心中的困惑迎刃而解,於是我將這部分資料進行整理放到了github上,歡迎star檢視最新更新內容, https://github.com/xirong/my-git

如何選購高效能的雙千兆路由?這裡!

百兆乃至千兆的光纖網路正在普及,傳統路由器已跟不上時代的速度了,不少人的眼光已投向千兆路由,不過真千兆、假千兆,往往像李逵和李鬼,讓人傻傻分不清楚,下面就借你一雙慧眼,看個真真切切,明明白白。 一、什麼是千兆路由? 在選擇千兆路由器之前,我們得弄清千兆路由究竟是何方神

淘粉網省錢優惠券是騙人的嗎?這裡

淘粉網其實跟很多平臺一樣,都是主打購物省錢的模式,但是這個淘粉網不同的是,它會在你進入是送你520元體驗金,然後每天給你釋放0.16元,平臺是0.01元就能夠提現,其實很多人說這是騙局嗎? 其實今天來說

nRF24L01微控制器通訊的總結--會用

1周時間,我從一個沒用過STC微控制器,不知道什麼叫SPI介面的“文盲”,把nRF24L01的整個通訊過程弄到完全沒有bug.。興奮之餘來小屁一下。給那些正在奮鬥著這個牛逼的晶片的小牛們小炫一下。希望有所幫助。屁話少說。正題:  基本的東西我理解了,那就是:1.用5根線的S

執行緒池的基本原理,

原文地址: http://blog.jboost.cn/2019/07/05/threadpool.html   本文內容是基於研發部門內部的分享整理,記錄下來供學習或回顧。 1. 為什麼要用執行緒池 降低資源消耗。通過重複利用已建立的執行緒降低執行緒建立、銷燬執行緒造成的

吳恩達deepLearning.ai迴圈神經網路RNN學習筆記_!!!(理論篇)

  前言 目錄:     RNN提出的背景         - 一個問題         - 為什

吳恩達deepLearning.ai迴圈神經網路RNN學習筆記_沒有複雜數學公式,!!!(理論篇)

  本篇文章被Google中國社群組織人轉發,評價: 條理清晰,寫的很詳細!  被阿里演算法工程師點在看!  所以很值得一看!   前言 目錄:     RNN提出的背景    &nbs

Vue生命週期,我奶奶

最近一直在學習Vue,而vue生命週期是我們不可能繞開的一個很核心的知識點,今天來簡單的梳理一下大概的內容。 # 一、鉤子函式 在一開始學習的時候,總有鉤子函式這個名詞冒出來,而且在vue官網文件中也頻繁出現,也相信給很多初學者帶來了困擾。那到底什麼是鉤子函式呢? 按我個人的理解,鉤子函式就是一個函式,

vue元件通訊全揭祕

這文章在一年前已經寫出來了。今天還是決定放出來供所有人學習。為什麼我會寫vue元件通訊全揭祕,因為無論任何元件模式的框架。元件是核心,只有把元件寫元件之間能理順了。專案也就自然順了。內容非常多,而且一年後我覺得元件的通訊部分的沒有任何變化。沒有任何一點過時。希望對大家有幫助 第01課:給你一個不學 Vue

重量級鎖 synchronized(不後悔,

synchronized關鍵字並非一開始就該物件加上重量級鎖,也是從偏向鎖,輕量級鎖,再到重量級鎖的過程。這個過程也告訴我們,假如我們一開始就知道某個同步程式碼塊的競爭很激烈、很慢的話,那麼我們一開始就應該使用重量級鎖了,從而省掉一些鎖轉換的開銷。 互斥鎖(重量級鎖)也稱為阻塞同步、悲觀鎖

自旋鎖和自適應自旋鎖(不後悔,

自旋鎖 所謂自旋,就是指當有另外一個執行緒來競爭鎖時,這個執行緒會在原地迴圈等待,而不是把該執行緒給阻塞,直到那個獲得鎖的執行緒釋放鎖之後,這個執行緒就可以馬上獲得鎖的。鎖在原地迴圈的時候,是會消耗cpu的,就相當於在執行一個啥也沒有的for迴圈。 本來一個執行緒把鎖釋放之後,當前執行緒

輕量級鎖(不後悔,

輕量級鎖是由偏向鎖升級來的,偏向鎖執行在一個執行緒進入同步塊的情況下,當第二個執行緒加入鎖爭用的時候,偏向鎖就會升級為輕量級鎖(又叫做鎖膨脹);  輕量級鎖也被稱為非阻塞同步、樂觀鎖,因為這個過程並沒有把執行緒阻塞掛起,而是讓執行緒空迴圈等待,序列執行。 輕量級鎖適用於那些同步

偏向鎖(不後悔,

它會偏向第一個訪問鎖的執行緒,如果在執行過程中,同步鎖只有一個執行緒訪問,不存在多執行緒爭用的情況,則執行緒是不需要觸發同步的,這種情況下,就會給執行緒加一個偏向鎖。 如果在執行過程中,遇到了其他執行緒搶佔鎖,則持有偏向鎖的執行緒會被掛起,JVM會消除它身上的偏向鎖,將鎖恢復到標準的輕

樂觀鎖和悲觀鎖(不後悔,

鎖從巨集觀上分類,分為樂觀鎖和悲觀鎖 樂觀鎖是一種樂觀的思想,每次獲取資料的時候都不擔心資料會被修改,所以每次獲取資料的時候都不會加鎖,但是在更新的時候需要判斷該資料是否被人修改過.如果資料被其他執行緒修改,則不進行資料更新,否則,更新.由於資料沒有加鎖,期間該資料可以被其他執行緒進行讀寫操

hibernate和mybatis的區別(不後悔,

①hibernate是一個標準的orm(物件關係對映)框架,通過JavaBean和資料庫的對映結構來自動生成sql;mybatis是不完全的orm框架,專注於sql本身,需要程式設計師自己寫sql; ②hibernate對sql的優化和修改比較困難,適合於需求變化不多的中小型專案,如ERP(

vue元件通訊--注意事項及經驗總結

元件間的通訊是是實際開發中非常常用的一環,如何使用對專案整體設計、開發、規範都有很實際的的作用,我在專案開發中對此深有體會,總結下vue元件間通訊的幾種方式,討論下各自的使用場景 文章對相關場景預覽 父->子元件間的資料傳遞 子->父元件間的資料傳遞

Vue元件通訊之二:事件監聽函式$emit/$on/$off

在vue2.x版本中自定義時間都需要通過$emit/$on/$off函式來進行觸發、監聽和取消監聽。 如果瞭解過JavaScript的設計模式-------觀察者模式,一定知道dispatchEvent和addEventListener這兩個方法。Vue元件中也有與之類似的模式,子元件用$emi

Vue元件通訊之一props

元件間通訊是元件開發時非常重要的一個環節,Vue在元件鍵通訊提供了直接訪問元件例項的方法,同時也提供了自定義事件機制,通過廣播、委派、監聽等形式跨元件的函式呼叫。 在元件的例項中,Vue提供了三個屬性對其父子元件以及根例項進行直接訪問: (1)$parent:父元件例項; (2)$chi

簡析區塊鏈錢包,

在數字資產世界裡,區塊鏈錢包(Block Chain Wallet)是一個金鑰 (包含私鑰和公鑰) 的管理工具,它只包含金鑰而不是確切的某一個代幣;錢包中包含成對的私鑰和公鑰,使用者用私鑰來簽名交易,從而證明該使用者擁有交易的輸出權;而輸出的交易資訊則儲存在區塊鏈中;使用者在使用錢包時, 你