实际开发工做中,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"]
}
复制代码
……
复制代码