发布订阅模式其实与vue无关,完全是ES6的代码,但是它可以通过这种模式实现非父子组件的通信
store.js文件
首先创建一个store.js文件,用于提供发布与订阅方法
export default {
datalist: [], //存放带一个参数的函数集合
//订阅
subscribe(fun) {
this.datalist.push(fun) //将一个带一个参数的函数添加到datalist中
},
//发布
publish(value) {
this.datalist.forEach(fun=>{
fun(value) //遍历datalist中的函数并且立即执行 (函数带几个参数需要自己根据自己的实际情况来决定)
})
}
}
App.vue组件
我有一个根组件App.vue根组件 它下面有一个AChild.vue子组件,和一个BChild.vue子组件
<template>
<div>
<AChild></AChild>
<BChild></BChild>
</div>
</template>
<script>
import AChild from "./components/AChild.vue" //导入AChild组件模板
import BChild from "./components/BChild.vue";
export default {
inheritAttrs: false,
data() {
return {
nvaTitle:"首页"
}
},
components: {
AChild,
BChild
}
}
</script>
<style>
#app{
width: 100%;
max-width: 95%;
}
* {
margin: 0px;
padding: 0px
}
ul {
list-style: none;
}
body{
display:block
}
</style>
AChild.vue
<template>
<div>
{{title}}
</div>
</template>
<script>
import store from "./store.js" //导入store.js
export default {
inheritAttrs: false,
data() {
return {
title: "我是标题"
}
},
mounted(){ //钩子函数,项目一启动立即订阅,只要谁触发了store.publish 发布函数,这里能立即获取到发布的值
store.subscribe((value)=>{
this.title=value; //将发布的值赋值给title
})
}
}
</script>
<style scoped>
div{
background: gray;
}
</style>
BChild.vue
<template>
<div>
<ul>
<li v-for="item in titleArr" :key="item" @click="handelClick(item)">{{item}}</li>
</ul>
</div>
</template>
<script >
import store from './store';
export default{
inheritAttrs:false,
data(){
return{
titleArr:["首页", "列表", "我的"]
}
},
methods:{
handelClick(item){
store.publish(item); //谁点击了li标签,立即发布数据(我发布的数据就是我点击的li的文本,所以我发布的就是一个文本)
}
}
}
</script>