實際開發工做中,Vue總會組件化開發,這個時候,組件與組件之間的通訊方式就很重要了,一般使用以下選擇:props/emit;EventBus;vuex……vue
這是使用很普遍很重要的一個方法,父組件向子組件傳值的時候子組件使用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>
複製代碼
事件總線的方式用於比較簡單的場景,可是卻很便捷有效。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
})
複製代碼
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;
}
}
複製代碼
props對於父子組件間的通訊很好,可是若是層級過多,依舊使用props就會顯得很臃腫,
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>
複製代碼
provide/inject成對使用的,只要上一級聲明瞭provide,不管子組件有多深均可以經過inject訪問到provide的值。ui
// 上一級
export default {
provide() {
return {
target: this.baseTarget
}
},
data() {
return {
baseTarget: "xxxx"
}
}
}
// 下一級
export default {
inject: ["target"]
}
複製代碼
……
複製代碼