myEventBus.html
<script>
var eventbus = {
fnObj:{
//abc:[fn1,fn2], 可以多次订阅同一个事件,因此每个 key 对应一个数组
},
$on: function (id, fn) {
if(!this.fnObj[id]){
this.fnObj[id] = [fn]
}else{
this.fnObj[id].push(fn)
}
},
$emit: function (id, data) {
if(this.fnObj[id]){
var fnArr = this.fnObj[id]
// 当事件触发时,循环执行每个 key 对应的 所有function
for(var i = 0;i<fnArr.length;i++){
var fn = fnArr[i]
fn(data)
}
}else{
console.log('异常,函数不存在')
}
}
}
eventbus.$on('abc',function(data){
console.log(1)
})
eventbus.$on('abc',function(data){
console.log(2)
})
eventbus.$on('abc',function(data){
console.log(3)
})
eventbus.$on('abc',function(data){
console.log(4)
})
eventbus.$emit('abc','123')
</script>

不过如此的
Vuex
Vuex 应用程序开发的 状态管理模式,集中式管理应用所有组件的状态,进行组件通讯
安装插件,引入 Vuex,创建 store 实例,配置到 Vue 实例中
为防止状态,方法声明等过分重复和冗余,Vuex 提供了一些辅助函数,mapState,mapGetters,mapMutations,mapActions,可使用扩展运算符展开,其中:
mapState,mapGetters声明在 computed 中
mapMutations,mapActions 声明在 methods 中
创建 store 实例,核心属性:
State:一个对象,包含全部的应用状态。作为唯一数据源存在。store实例会注入到根组件下的所有子组件
Getters:state 中数据派生出一些状态类似计算属性,返回值会根据它的依赖被缓存起来,只有依赖发生改变时才会被重新计算,state 作为其第一个参数.
Mutations:更改 store 中的状态,store.commit('事件名',payload参数可选)触发,只做同步操作,
Actions:类似于Mutations, 提交的是 mutation,而不是直接变更状态,可以包含任意异步操作。this.$store.dispatch分发,异步执行完毕,返回封装的promise 对象。接受一个与 store 实例具有相同方法和属性的对象
Modules:为防止 store 对象过于复杂,可将其分割成模块,每个模块都有自己的State,Getters,Mutations,Actions,甚至可以嵌套子模块

// main.js
import Vue from 'vue'
import App from './App.vue'
import Vuex from 'vuex'
import numModule from './numModule.js'
Vue.use(Vuex)
var store = new Vuex.Store({
modules:{
numModule
}
})
new Vue({
store,
render: h => h(App)
}).$mount('#app')
// numModule.js
export default {
state: {
num: 1
},
getters: {
getNum(state) { // 可以返回一些派生状态
return state.num
}
},
mutations: {
// 同步修改状态的函数
changeNum(state, payload) {
state.num += payload.num
},
// 异步时,开发工具会遗漏快照,不便于调试(不推荐)
testAsync(state, data) {
// 模拟服务器获取数据
setTimeout(function () {
state.num += data
}, 0)
}
},
actions: {
// 异步获取数据,提交给 mutation 进行修改
incNumByService(store) {
setTimeout(function () {
var serviceData = 0.1
store.commit('changeNum', {
num: serviceData
})
}, 0)
}
}
}
// App.vue
<template>
<div>
第一组件
<p>state:{{$store.state.numModule.num}}</p>
<!-- getters:方式为只读,数据更安全 -->
<p>getters:{{$store.getters.getNum}}</p>
<p>MapGetters:{{gn}}</p>
<button @click="changeNum">mutation同步</button>
<button @click="testAsync">mutation异步</button>
<button @click="testActions">action异步</button>
<Son />
</div>
</template>
<script>
import { mapGetters } from "vuex";
import Son from "./components/son";
export default {
components: {
Son
},
methods: {
changeNum() {
this.$store.commit({
type: "changeNum",
num: 1
});
//效果同上
// this.$store.commit("changeNum",{
// num: 1
// });
},
testAsync() {
this.$store.commit("testAsync", 10);
},
testActions() {
// dispatch 异步执行完毕,返回 封装的promise 对象
this.$store.dispatch("incNumByService").then(res => {
alert("dispatch执行完毕");
});
}
},
computed: {
//使用对象展开运算符将 getter 混入 computed 对象中
//如果想将一个 getter 属性另取一个名字,使用对象形式:
...mapGetters({
gn: "getNum" // 把 `this.gn` 映射为 `this.$store.getters.getNum`
})
}
};
</script>
// Son.vue
<template>
<div>
第二组件
<button>state:{{$store.state.numModule.num}}</button>
<!-- getters:方式为只读,数据更安全 -->
<button>getters:{{$store.getters.getNum}}</button>
<button @click="clickMe">MapGetters:{{gn}}</button>
</div>
</template>
<script>
import { mapGetters } from "vuex";
export default {
computed: {
...mapGetters({
gn: "getNum"
})
}
};
</script>