Appearance
消息发布订阅示例
消息发布订阅主要用于解决页面中不同层级的组件之前通讯的问题
代码示例
主页面
- 主页面中用到了头部区域组件与内容区域组件,两个组件之间需要进行通讯,这个时候就可以用到消息发布订阅
vue
<template>
<!-- 容器 -->
<div>
<!-- 头部区域 -->
<v-header :unique="unique" />
<!-- 内容区域 -->
<v-content :unique="unique" />
</div>
</template>
<script>
import util from '@/assets/js/util';
import vHeader from '@/modules/pex/components/header';
import vContent from '@/modules/pex/components/content';
export default {
components: {
vHeader,
vContent,
},
data() {
return {
unique: util.generateShortId(true), //TODO:当前页面唯一的key
};
},
};
</script>
常量文件
vue
/**
* 消息主题
*/
export const TOPIC = {
PEX_BILL_QUERY_REFRESH: 'PEX_BILL_QUERY_REFRESH', //单据查询刷新操作
};
头部区域
- TODO:发布消息时,应该保证当前页面的消息主题具有唯一性,如果消息主题不唯一,则同时打开多个页面时,可能存在消息订阅错乱的问题(例如报销系统单据新增页面,由于单据块组件会在不同类型的报销单新增页面使用,所以同时打开多类型单据报销页面时,不同类型的单据新增页面的消息主题应该具有唯一性,以保证同一个组件块在不同页面使用时消息主题不会相互干扰)
- TODO:可以通过消息主题与当前页面唯一的key结合起来使用,保证唯一性
- TODO:发布消息时,可以通过全局对象
$observable
的publish
方法来发布消息,publish
方法第一个参数为消息主题,第二个参数开始是可选参数,可供发布消息时额外的传递参数,可同时传递多个参数
vue
<template>
<!-- 头部区域 -->
<el-button @click="onRefresh">刷新</el-button>
</template>
<script>
import { TOPIC } from '@/modules/pex/common/constant';
export default {
props: {
unique: String, //当前页面唯一的key
},
methods: {
/**
* 处理刷新
* 1、发布消息通知内容区域进行更新
*/
onRefresh() {
// TODO:发布消息时,应该保证当前页面的消息主题具有唯一性,如果消息主题不唯一,则同时打开多个页面时,可能存在消息订阅错乱的问题(例如报销系统单据新增页面,由于单据块组件会在不同类型的报销单新增页面使用,所以同时打开多类型单据报销页面时,不同类型的单据新增页面的消息主题应该具有唯一性,以保证同一个组件块在不同页面使用时消息主题不会相互干扰)
// TODO:可以通过消息主题与当前页面唯一的key结合起来使用,保证唯一性
// TODO:发布消息时,可以通过全局对象$observable的publish方法来发布消息,publish方法第一个参数为消息主题,第二个参数开始是可选参数,可供发布消息时额外的传递参数,可同时传递多个参数
let params = {};
this.$observable.publish(
`${TOPIC.PEX_BILL_QUERY_REFRESH}${this.unique}`,
params
);
},
},
};
</script>
内容区域
- TODO:组件创建时,需要订阅消息
- TODO:订阅消息时,可以通过全局对象
$observable
的subscribe
方法来订阅消息,subscribe
方法第一个参数为消息主题,第二个参数为处理消息的函数 - TODO:取消订阅消息时,可以通过全局对象
$observable
的unsubscribe
方法来订阅消息,unsubscribe
方法第一个参数为消息主题,第二个参数为处理消息的函数 - TODO:处理接受到的消息
- TODO:组件销毁时,需要取消订阅消息
vue
<!-- 内容区域 -->
<template>
</template>
<script>
import { TOPIC } from '@/modules/pex/common/constant';
export default {
props: {
unique: String, //当前页面唯一的key
},
created() {
// TODO:组件创建时,需要订阅消息
this.subscribe();
},
methods: {
/**
* 消息订阅
* 1、订阅单据查询刷新操作
*/
subscribe() {
// TODO:订阅消息时,可以通过全局对象$observable的subscribe方法来订阅消息,subscribe方法第一个参数为消息主题,第二个参数为处理消息的函数
this.$observable.subscribe(
`${TOPIC.PEX_BILL_QUERY_REFRESH}${this.unique}`,
this.onBillQueryRefresh
);
},
/**
* 取消订阅
* 1、取消订阅单据查询刷新操作
*/
unsubscribe() {
// TODO:取消订阅消息时,可以通过全局对象$observable的unsubscribe方法来订阅消息,unsubscribe方法第一个参数为消息主题,第二个参数为处理消息的函数
this.$observable.unsubscribe(
`${TOPIC.PEX_BILL_QUERY_REFRESH}${this.unique}`,
this.onBillQueryRefresh
);
},
/**
* 处理单据查询刷新操作
*/
onBillQueryRefresh(params) {
// TODO:处理接受到的消息
},
},
beforeDestroy() {
// TODO:组件销毁时,需要取消订阅消息
this.unsubscribe();
},
};
</script>