天天看點

父子元件,非父子元件通信一、Vue官方文檔說明二、父子元件消息傳遞示例3.非父子元件通信 

一、Vue官方文檔說明

在 Vue 中,父子元件的關系可以總結為 prop 向下傳遞,事件向上傳遞。父元件通過 prop給子元件下發資料,子元件通過事件給父元件發送消息。看看它們是怎麼工作的。

父子元件,非父子元件通信一、Vue官方文檔說明二、父子元件消息傳遞示例3.非父子元件通信 

- - - - - - - - - - - - - - - - ✂- - - - - - - - - - - - - -✂-- - - - - - -- - - - - - - -✂- - - - - - -- - - - - - - - - -

二、父子元件消息傳遞示例

1.父元件傳遞資料給子元件

父元件資料如何傳遞給子元件呢?

使用 Prop 傳遞資料

元件執行個體的作用域是孤立的。這意味着不能 (也不應該) 在子元件的模闆内直接引用父元件的資料。父元件的資料需要通過 prop 才能下發到子元件中。

<parent>
  <child :child-msg="msg"></child> //這裡必須要用 - 代替駝峰
</parent>

data(){
  return {
    msg: [1,2,3]
  };
}
           

子元件要顯式地用 

props

 選項聲明它預期的資料:

Vue.component('child', {
  // 聲明 props
  props: ['childMsg'],
  // 就像 data 一樣,prop 也可以在模闆中使用
  // 同樣也可以在 vm 執行個體中通過 this.childMsg 來使用
  template: '<span>{{ childMsg }}</span>'
})
           

PS: 

props

 選項說明:

方式1:

props: ['childMsg']
           

方式2 :

props: {
  childMsg: Array // 這樣可以指定傳入的類型,如果類型不對,會警告
}
           

方式3:

props: {
  childMsg: {
    type: Array,
    default: [0,0,0] // 這樣可以指定預設的值
  }
}
           

這樣呢,就實作了父元件向子元件傳遞資料

2.子元件與父元件通信

那麼,如果子元件想要改變資料呢?這在vue中是不允許的,因為vue隻允許單向資料傳遞,這時候我們可以通過觸發事件來通知父元件改變資料,進而達到改變子元件資料的目的.

2.1 子元件:

<template>
    <div @click="tellParent"></div>
</template>
methods: {
    tellParent() {
        this.$emit('toParent', 'Hi, father!'); // 主動觸發toParent方法,'Hi, father!'為向父元件傳遞的資料
    }
}
           

2.2  父元件:

<parent>
    <child @toParent="change" :msg="msg"></child> // 監聽子元件觸發的toParent事件, 然後調用change方法
</parent>
methods: {
    change(msg) {
        this.msg = msg;
    }
}
           

3.非父子元件通信

如果2個元件不是父子元件那麼如何通信呢?這時可以通過eventHub來實作通信. 所謂eventHub就是建立一個事件中心,相當于中轉站,可以用它來傳遞事件和接收事件.

3.1 在共有元件中,建立一個空的 Vue 執行個體作為事件中心:

let Hub = new Vue(); //建立事件中心
           

元件1:

<template>
    <a @click="event"></a>
</template>
methods: {
    event () {
        Hub.$emit('myEvent', 'Hi, there!'); // Hub觸發事件自定義事件‘myEvent’,并傳遞資訊“Hi, there!”
    }
}
           

元件2:

<template>
    <p>{{ message }}</p>
</template>
data() {
    return {
        message: '',
    }
},
created() {
    Hub.$on('myEvent', (msg) => { // Hub接收事件“myEvent”,并接受傳遞的資訊msg
        this.message = msg;
    });
}
           

這樣就實作了非父子元件之間的通信了.原理就是把Hub當作一個中轉站!

3.2  在main.js(vue-cli腳手架建立的項目)中,給data添加一個 名字為Hub的空vue對象

這時候,在任何元件都可以調用事件發射 接受的方法了。

// 根元件(this.$root)
new Vue({
 el: '#app',
 router,
 render: h => h(App),
 data: {
  // 空的執行個體放到根元件下,所有的子元件都能調用
  Hub: new Vue()
 }
})
           

假設 B 元件裡面有個按鈕,點選按鈕,把 123 傳遞給 A 元件

3.2.1 B元件内調用事件觸發↓

<button @click="submit">送出<button>
 
methods: {
  submit() {
   // 通過this.$root.Hub擷取此對象,再調用$emit方法
   this.$root.Hub.$emit('YOUR_EVENT_NAME', 123)
  }
}
           

A元件内調用事件接收↓

// 目前執行個體建立完成就監聽這個事件
created(){
    this.$root.Hub.$on('YOUR_EVENT_NAME', (yourData) => {
        handle(yourData)
    })
},
 
methods: {
    handle(yourData) {
        console.log(yourData)
    }
},
 
// 在元件銷毀時别忘了解除事件綁定
beforeDestroy() {
    this.$root.Hub.$off('YOUR_EVENT_NAME')
},