vue組件之間的通訊

注意1:事件總線是處理同一路由下複雜的父子關係組件的,若是跨路由是有問題的,由於監聽的界面確定尚未加載,因此這一點要記清楚了。
注意2:爲了防止$on監聽界面尚未加載完畢可使用在$emit外面包一層$nextTick等待組件都加載完畢,下面例子會講解
注意3:常常會出現重複監聽的問題,是由於沒有關閉監聽,隨意在今天完畢之後,界面將要銷燬的時候關閉監聽vue

beforeDestroy () {
    eventBus.$off('recommendEmit')
  }

一、父組件-->子組件後端

父組件代碼app

<child-page :child-msg="data"></child-page>

子組件代碼函數

export default {
  name: 'child',
  props: {
    child-msg: String
  }
};

或者this.$children 訪問它全部的子組件, 並且能夠遞歸向下無限訪問,this

二、子組件-->父組件
發送事件/監聽事件
子組件中某函數內發送事件:spa

this.$emit('toparentevent', 'data');

父組件監聽事件:3d

<Child :msg="msg" @toparentevent="todo()"></Child>

或者使用 this.$parent 能夠直接訪問該組件的父實例或組件,並且能夠遞歸向上訪問code

三、父組件直接獲取子組件屬性或方法
給要調用的子組件起個名字。將名字設置爲子組件 ref 屬性的值。
<!-- 子組件。 ref的值是組件引用的名稱 -->component

<child-component ref="aName"></child-component>

父組件中經過 $refs.組件名 來得到子組件,也就能夠調用子組件的屬性和方法了。router

var child = this.$refs.aName
child.屬性
child.方法()

最重要的方式:vue組件通訊,中央控制總線

clipboard.png

實現不一樣組價之間的通訊,其實很簡單,請看下面步驟
一、新建control.js, 注意兩行代碼寫完回車一下要否則報錯。

import Vue from 'vue'
export default new Vue()

二、在須要發射或者監聽的界面引入,並使用。
這就是一箇中央事件總線,而後咱們在須要發送或者監聽事件的界面引入這個文件,而後使用裏面的$on/$emit來監聽和發射消息便可。

import control from './control.js'
// 監聽
mounted () {
control.$on('須要監聽的事件名稱', ()=> {
    // 須要執行的命令
}

// 發射事件
methods () {
    this.$nextTick(() => {
        emitFun() {
            control.$emit("childEmitFun", "參數");
        }
     })
},
beforeDestory () {
    control.$off('childEmitfun')
}

三、實例
A: 目錄, 界面

clipboard.png

clipboard.png

都引入到app.vue中

clipboard.png

B: ParentOne.vue

<template>
    <div>
        <br/>
        <br/>
        <v-button @click="emitOneFun()" type="primary">發送給兄弟組件</v-button>
    </div>
</template>
<script>
import center from '../center/center.js'
export default {
    name: "parentOne",
    mounted() {
        
    },
    methods: {
        emitOneFun() {
            this.nextTick(() => {
                center.$emit("emitParentOne");
            })
        }
    }
}
</script>

C: parentTwo.vue

<template>
<div>
    <br/>
    <br/>
    <v-button @click="emitChildrenOneFun" type="primary">發送消息到子組件</v-button>
</div>
</template>
<script>
    import center from "../center/center.js"
    export default {
        mounted () {
            center.$on("emitParentOne", ()=> {
                alert("接收兄弟組件傳遞過來的信息");
            })
        },
        methods: {
            emitChildrenOneFun () {
                this.nextTick(() => {
                    center.$emit("emitChildrenOne");
                })
            }
        },
        beforeDestory () {
            center.$off('emitChildrenOne')
        }
    }
</script>

D: ChildrenOne.vue

<script>
    import center from "../../center/center.js"
    export default {
        mounted () {
            center.$on("emitChildrenOne", ()=> {
                alert("監聽發送childrenOne的事件")
            })
        },
        beforeDestory () {
            center.$off('emitChildrenOne')
        }
    }
</script>
beforecreate : 能夠在這加個loading事件 
created :在這結束loading,還作一些初始化,實現函數自執行 
mounted : 在這發起後端請求,拿回數據,配合路由鉤子作一些事情
beforeDestroy: 你確認刪除XX嗎? destroyed :當前組件已被刪除,清空相關內容

事件總線完整實例一個父組件一個子組件
Recommend.vue 父

// 組件之間的通訊,要實現兄弟組件,父子組件,父孫組件之間的通訊
// 使用系統總線
<template>
  <div>
    <recommend-list></recommend-list>
    <div @click="recommendEmitFun({name: 'zxc'})">事件總線發射事件</div>
  </div>
</template>
<script>
import RecommendList from '../components/RecommendList'
import eventBus from '../assets/eventBus'
export default {
  name: 'Recommend',
  data () {
    return {
    }
  },
  mounted () {
    // 接收事件
    eventBus.$on('recommendListEmit', (params) => {
      console.log(params, 'recommendListEmit')
    })
  },
  methods: {
    recommendEmitFun (params) {
      console.log(params, '發送事件 recommendEmit')
      this.$nextTick(() => {
        eventBus.$emit('recommendEmit', params)
      })
    }
  },
  beforeDestroy () {
    eventBus.$off('recommendListEmit')
  },
  components: {
    RecommendList
  }
}
</script>
<style scoped>

</style>

RecommendList 子

<template>
  <div>
    <div v-for="(item, index) of recommendList" :key="index">
      <div @click="recommendList(index, item)">
        <span>{{index+1}}. </span>
        <span>{{item.title}}</span>
      </div>
    </div>
    <div @click="recommendlistFun()">emit</div>
  </div>
</template>
<script>
import eventBus from '../assets/eventBus'
export default {
  name: 'RecommendList',
  created () {
    eventBus.$on('recommendEmit', (params) => {
      console.log(params, '接受事件總線')
    })
  },
  data () {
    return {
      recommendList: [
        {
          type: 'nba',
          title: '杜蘭特復出,勇士大勝猛龍',
          content: '大比分1:3落後的狀況下,杜蘭特傷愈復出,是否能帶領球隊獲勝?'
        },
        {
          type: 'nba',
          title: '法國跑車帕克宣佈退役',
          content: '黃蜂隊買斷帕克,帕克宣佈退役,再也不打球。'
        }
      ],
      recommendDetail (index, item) {
        this.$router.push({name: 'detail', params: {id: index, item: item}})
      }
    }
  },
  methods: {
    recommendlistFun () {
      console.log('發送 recommendListEmit')
      this.$nextTick(() => {
        eventBus.$emit('recommendListEmit', {name: 'recommendList'})
      })
    }
  },
  beforeDestroy () {
    eventBus.$off('recommendEmit')
  }
}
</script>
相關文章
相關標籤/搜索