之前使用的组件间通信使用的都是基于Vue的一些属性,方法等。本篇基于原生JS的订阅发布来实现跨组件通信。
订阅发布模型代码如下
store.js
export default{
datalist:[],
sub(cb){
this.datalist.push(cb)
},
pub(data){
this.datalist.forEach(cb => {cb(data)});
}
}
App.vue
<template>
<Navbar></Navbar>
<Tabbar />
</template>
<script>
import { computed } from 'vue';
import Navbar from './Navbar.vue';
import Tabbar from './Tabbar.vue'
export default {
data() {
return { navTitle: '首页' }
},
components: {
Navbar, Tabbar
},
methods: {
changeTitle(title) {
this.navTitle = title
console.log(this.navTitle)
}
},
provide() {
return {
changeTitle: this.changeTitle,
navTitle: computed(()=>this.navTitle)
}
}
}
</script>
<style>
* {
margin: 0;
padding: 0;
}
</style>
Navbar.vue
<template>
<div>
<button>返回</button>
<span>{{ navTitle }}</span>
<button>首页</button>
</div>
</template>
<script>
import store from './store'
export default {
data() {
return {
navTitle: '首页'
}
},
mounted() {
store.sub((value) => {
console.log(value)
this.navTitle=value
})
}
}
</script>
<style scoped>
div {
display: flex;
width: 100%;
justify-content: space-between;
height: 50px;
line-height: 50px;
background: orange;
}
</style>
Tabbar.vue
<template>
<ul>
<TabbarItem v-for="data in datalist" :key="data" :item="data">{{ data }}</TabbarItem>
</ul>
</template>
<script>
import TabbarItem from './TabbarItem.vue';
export default{
data(){
return{
datalist:["首页","列表","我的"]
}
},
components:{
TabbarItem
}
}
</script>
<style scoped>
ul{
display: flex;
position: fixed;
bottom: 0;
width: 100%;
height: 50px;
line-height: 50px;
}
li{
flex:1;
text-align: center;
}
</style>
TabbarItem.vue
<template>
<li @click="handleClick">{{ item }}</li>
</template>
<script>
import store from './store'
export default {
props: ["item"],
methods: {
handleClick() {
store.pub(this.item)
}
}
}
</script>