Vue組件間通訊方式彙總

1. Vue組件間通訊方式彙總

1.1 概述

實際開發工做中,Vue總會組件化開發,這個時候,組件與組件之間的通訊方式就很重要了,一般使用以下選擇:props/emit;EventBus;vuex……vue

1.1.1 props/emit

這是使用很普遍很重要的一個方法,父組件向子組件傳值的時候子組件使用props接受,因爲單向數據流的緣由,子組件向父組件傳值只能經過時間觸發,則使用emit事件。vuex

// 父組件
<template>
  <div class="sup-page">
    <sub-page :propVal="propVal" @emitSupPage="getEmitSub"/>
  </div>
</template>
<script>
export default {
  data() {
    return {
      propVal: "test prop value"
    }
  },
  methods: {
    getEmitSub() {
      console.log("get info from sub page")
    }
  }
}
</script>


// 子組件
<template>
  <div class="sub-page">
    {{propVal}}
    <button type="button" @click="emitSupPage">Click</button>
  </div>
</template>
<script>
export default {
  props: {
    propVal: {
      type: String,
      required: true,
      default: "test prop value"
    }
  },
  methods: {
    emitSupPage() {
      this.$emit("emitSupPage", payload); // 經過emit向上傳遞,第二個參數能夠是任何類型的值
    }
  }
}
</script>
複製代碼

1.1.2 EventBus

事件總線的方式用於比較簡單的場景,可是卻很便捷有效。EventBus原理就是新建一個Vue實例。session

//event-bus.js
import Vue from "vue"
import default new Vue()

//page1.vue
import EventBus from "event-bus.js"
EventBus.$emit("emitEvent", payload)

//page2.vue
import EventBus from "event-bus.js"
EventBus.$on("emitEvent", payload => {
  // TODO
})
複製代碼

1.1.3 Vuex

Vuex是Vue周邊一個大的生態系統,一句兩句話確定是說不完的,最好的仍是查閱官方文檔,下面是簡單的應用。ide

//index.js => 入口文件,導出實例
import Vue from "vue"
import Vuex from "vuex"
import state from "./state"
import actions from "./actions"
import mutations from "./mutations"
Vue.use(Vuex)
export default new Vuex.Store({state, actions, mutations})

// state.js => 初始化數據
let userStatus = 0;
try {
  if (sesseionStorage.userStatus) {
    userStatus = SessionStorage.userStatus
  }
} catch (e) {
  // TODO
}
export default { userStatus }

// actions.js => 接受視圖層dispatch過來的事件(this.$store.dispatch(event, payload))
export default {
  changeStatus({ commit }, param) {
    // handle logic operation
    commit("changeStatus", param) // 傳遞事件到mutations.js
  }
}

// mutations.js => 接受actions.js傳遞的事件,處理改變視圖層
export default {
  changeStatus(state, param) {
    state.userStatus = param;
    sessionStorage.userStatus = param;
  }
}
複製代碼

1.1.4 attrs/listeners

props對於父子組件間的通訊很好,可是若是層級過多,依舊使用props就會顯得很臃腫,attrs/listeners就是很好的一個應用。組件化

// 父組件
<template>
  <div class="sup-page">
    <son-page :propVal="propVal" @emitListeners="emitListeners"/>
  </div>
</template>
<script>
export default {
  data() {
    return {
      propVal: "test-prop"
    }
  },
  methods: {
    emitListeners(val) {
      // TODO
    }
  }
}
</script>

// 子組件
<template>
  <div class="son-page">
    <sub-page v-bind="$attrs" v-on="$listeners" />
  </div>
</template>
<script>
export default {
  name: "son-page"
}
</script>

// 孫組件
<template>
  <div class="son-page">
    <button type="button" @click="emitListeners">Click</button>
  </div>
</template>
<script>
export default {
  created() {
    console.log(this.$attrs) // {propVal: "test-prop"}
  },
  methods: {
    emitListeners() {
      this.$listeners.emitListeners("click")
    }
  }
}
</script>
複製代碼

1.1.5 provide/inject

provide/inject成對使用的,只要上一級聲明瞭provide,不管子組件有多深均可以經過inject訪問到provide的值。ui

// 上一級
export default {
  provide() {
    return {
      target: this.baseTarget
    }
  },
  data() {
    return {
      baseTarget: "xxxx"
    }
  }
}

// 下一級
export default {
  inject: ["target"]
}
複製代碼

1.1.6 OTHER WAYS

……
複製代碼

相關文章
相關標籤/搜索