Vue 组件间通信方法汇总
Vue 組件間通信方法匯總
?? 更多前端技術和知識點,搜索訂閱號 JS 菌 訂閱
除了使用 Vuex 方法外,vue 提供了各種各樣的組件間通信的方案。文章整理一下父子組件、兄弟組件、祖先后代組件間是如何通信的。 ?
? 父子組件通信
props 和 $emit 父子組件通信
子組件有時需要與父組件進行溝通,溝通的方式就是子組件 emit 事件,父組件通過監聽這個事件來做進一步動作。而父組件與子組件通信則使用 props
假設這里有一個父組件并引入了一個子組件 my-comp:
<my-comp v-for="msg in msgs" :key="msg.id" :msg="msg"></my-comp> 復制代碼父組件有一系列 msg 數據需要通過子組件渲染,將 msg 作為 prop 傳遞給子組件即可:
import MyComp from '@/components/MyComp.vue'export default {name: 'home',components: {MyComp},data () {return {msgs: [{id: 1, data: 'hello js'}, {id: 2, data: 'css world'}, {id: 3, data: 'animated style'}]}} } 復制代碼我們通過點擊子組件每一項觸發一個事件,父組件監聽這個事件去動態改變子組件的 color 樣式,這就是父組件監聽子組件事件,事件處理函數可以從子組件傳遞值給父組件:
<my-comp v-for="msg in msgs" :key="msg.id" :msg="msg" :colored="colored" @handle-change-color="handleChangeColor"></my-comp> 復制代碼首先增加一個事件 handle-change-color 當這個事件被觸發時修改名為 color 的 data,然后將 colored 通過 props 傳入到子組件:
import MyComp from '@/components/MyComp.vue'export default {name: 'home',components: { // 注冊組件MyComp},data () {return {colored: false, // 狀態msgs: [{id: 1, data: 'hello js'}, {id: 2, data: 'css world'}, {id: 3, data: 'animated style'}]}},methods: {handleChangeColor () {this.colored = !this.colored // 監聽事件動態改變 colored}// handleChangeColor (param) { // 子組件觸發的事件可能包含參數} } 復制代碼然后編輯子組件:
<div><div @click="handleClick" :style="{color}">{{msg.id}} - {{msg.data}} ?</div> </div> 復制代碼首先渲染數據,并監聽 click 點擊事件,當點擊觸發事件處理函數 handleClick
export default {name: 'MyComp',computed: {color () { // color 為樣式return this.colored ? 'red' : 'black' // 根據父組件傳入的 props 動態修改樣式}},props: ['msg', 'colored'],methods: {handleClick (e) {this.$emit('handle-change-color') // 使用 $emit 方法觸發父組件 handle-change-color 事件// this.$emit('handler', 'param') // 還可以給事件傳遞參數}} } 復制代碼子組件接收 colored 父組件傳遞來的 prop,返回一個計算后的屬性 color,根據 colored 返回不同樣式。handleClick 處理當子組件元素被點擊時 $emit 派發父組件的 handle-change-color 事件
效果如下:
父組件 $children 操作子組件
使用 $children 操作子組件。如上述例子中,colored 被定義在父組件中,可以將其移動到子組件中,并在父組件通過 $children 訪問到子組件:
<template><div @click="handleClick" class="home"><my-comp v-for="msg in msgs" :key="msg.id" :msg="msg"></my-comp></div> </template> 復制代碼handleClick 事件被放置在 div 中
import MyComp from '@/components/MyComp.vue'export default {// ...data () {return {msgs: [{// ...}]}},methods: {handleClick () {this.$children.forEach(child => {child.$data.colored = !child.$data.colored // 逐一控制子組件的 $data})}} } 復制代碼在子組件中不需要 $emit 事件,只需維護一個 data:
export default {name: 'MyComp',data () {return {colored: false // colored 狀態}},computed: {color () {return this.colored ? 'red' : 'black'}},props: ['msg'] } 復制代碼子組件 $parent 訪問父組件
子組件可通過 $parent 來修改父組件的 $data,因此 colored 定義在父組件中。
<template><div class="home"><my-comp v-for="msg in msgs" :key="msg.id" :msg="msg" :colored="colored"></my-comp></div> </template> 復制代碼通過 prop 傳遞 colored 參數給子組件
import MyComp from '@/components/MyComp.vue'export default {name: 'home',components: {MyComp},data () {return {colored: false, // 父組件維護一個 colored 狀態msgs: [{// ...}]}} } 復制代碼父組件定義 colored 狀態
<template><div><div @click="handleClick" :style="{color}">{{msg.id}} - {{msg.data}} ?</div></div> </template> 復制代碼子組件渲染 msg 并監聽 click 事件
export default {// ...props: ['msg', 'colored'],methods: {handleClick (e) {this.$parent.$data.colored = !this.$parent.$data.colored}} } 復制代碼通過 $parent 訪問父組件,并修改 $data 狀態
? 非父子組件通信
中央事件總線
我們可以使用使用中央事件總線來處理非父子組件間的通信
具體步驟是創建一個 Vue 實例,然后 $on 監聽事件,$emit 來派發事件
// src/eventBus.jsimport Vue from 'vue' export default new Vue() 復制代碼首先創建并導出一個 Vue 實例
import bus from '@/eventbus'export default {// ...methods: {handleClick (e) {bus.$emit('change-color')}} } 復制代碼后代元素 $emit 觸發 eventBus 的事件
import bus from '@/eventbus'export default {// ...mounted () {bus.$on('change-color', () => {this.colored = !this.colored})} } 復制代碼祖先元素 $on 方法監聽 eventBus 的事件
provide/inject
適用于祖先和后代關系的組件間的通信,祖先元素通過 provide 提供一個值,后代元素則通過 inject 獲取到這個值。這個值默認是非響應的,如果是對象那么則是響應式的:
export default {name: 'home',provide () {return {colored: this.colored // 依賴于 data}},components: {MyComp},data () {return {colored: { // 必須為對象value: false},msgs: [{ // ... 復制代碼首先通過 provide 對外提供一個 colored,這個屬性依賴于 data 中的 colored,該變量必須為一個對象,才是響應式的。
?? 必須為一個對象
methods: {handleChangeColor () {this.colored.value = !this.colored.value}} 復制代碼祖先組件監聽事件或其他途徑去修改 data 改變狀態。
export default {name: 'MyComp',inject: ['colored'], // inject coloredcomputed: {color () {return this.colored.value ? 'red' : 'black' // do more...}}, // ... 復制代碼后代組件通過 inject 獲取到祖先組件提供的對象,根據對象做進一步動作。
$root 直接訪問根組件
根據官方的文檔,我們可以通過 $root 來直接訪問到 Vue 實例
比方說將數據存儲在 Vue 實例中:
// src/main.jsnew Vue({data () {return { // 在這里!!colored: false}},router,store,render: h => h(App) }).$mount('#app') 復制代碼然后我們在其他各個組件中都能夠使用:
export default {name: 'MyComp',// ...mounted () {console.log(this.$root) // 直接訪問到根組件},// ... } 復制代碼請關注我的訂閱號,不定期推送有關 JS 的技術文章,只談技術不談八卦 ?
轉載于:https://juejin.im/post/5cb5ac246fb9a068b748af2b
總結
以上是生活随笔為你收集整理的Vue 组件间通信方法汇总的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 常用取值
- 下一篇: [JDK8]性能优化之使用LongAdd