Vue.js中关于EventBus的抽像?
场景:
父组件:
<div v-for="(item,index) in corpKideList" :id="item.names" :key="index" :ref="item.names"> <component :is="item.key"
:ref="item.key"
:type="item.key"
:apply-obj.sync="infoApplyInstance"
:apply-id.sync="localApplyId"
@create="showCreatedTimes"
/>
</div>
corpKideList 会有很多数量不定的组件. 这些组件有一些共性的查询,例如:获取字典,加载附件
为了减少子组件对共性的查询次数,使用EventBus来合并为一次查询
现在:
获取字典(DictBus),加载附件(AttaBus). 在子组件加载时告诉告诉父组件需要哪些字典项, 组件需要哪些附件. 父组件侦听到当前corpKideList的子组件都加载完开始请求: 字典和附件。获得查询数据后再通过相应的EventBus把结果推到子组件中
BUG:
在多标签页时出现一个问题, 后面新开的标签页(B公司)加载的附件会冲掉已经打开的标签页(A公司)的附件. 发现问题后在原来的事件名中补了一个(公司.id)参数以免冲洗发生. 倒也OK
问题?
由于组件过多,需要一个一个的找到并附加参数, 有什么办法能在EventBus(AttaBus)类上解决此类问题?
回答:
一般来说,需要严格执行顺序的场景可以用 EventBus,如果主要为展示数据,应该用 vuex、pinia 等状态管理工具。
对于题主的场景,很明显应该用 vuex/pinia。然后接下来,就可以很方便的利用 vue computed 来获取你要的数据,不需要怎么修改。
回答:
在EventBus 中使用唯一标识符,更好的解决方案使用vuex
// EventBus.jsimport Vue from 'vue';
export const EventBus = new Vue();
// ParentComponent.vue
<template>
<div>
<child-component v-for="(item, index) in items" :key="index" :item="item" />
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
},
data() {
return {
items: [...] // 你的数据列表
};
}
};
</script>
// ChildComponent.vue
<template>
<!-- 组件内容 -->
</template>
<script>
import { EventBus } from './EventBus';
export default {
props: ['item'],
data() {
return {
uniqueEventName: ''
};
},
created() {
this.uniqueEventName = 'attaBus:' + this.item.id; // 使用公司 ID 作为唯一标识符
EventBus.$on(this.uniqueEventName, this.handleEvent);
EventBus.$emit('requestAttaBusData', this.uniqueEventName); // 请求数据
},
beforeDestroy() {
EventBus.$off(this.uniqueEventName, this.handleEvent); // 移除事件监听器
},
methods: {
handleEvent(data) {
// 处理事件数据
}
}
};
</script>
Vuex的方法
// store.jsimport Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
requestData: {},
responseData: {}
},
mutations: {
setRequestData(state, payload) {
state.requestData[payload.companyId] = payload.data;
},
setResponseData(state, payload) {
state.responseData[payload.companyId] = payload.data;
}
},
actions: {
async fetchData({ commit, state }, companyId) {
// 如果响应数据已经存在,则直接返回,不再发起请求
if (state.responseData[companyId]) {
return;
}
const requestData = state.requestData[companyId];
// Fetch data from API using requestData
const data = await api.fetchData(requestData);
commit('setResponseData', { companyId, data });
}
},
getters: {
getRequestData: (state) => (companyId) => {
return state.requestData[companyId];
},
getResponseData: (state) => (companyId) => {
return state.responseData[companyId];
}
}
});
父组件
// ParentComponent.vue<template>
<div>
<child-component
v-for="(item, index) in items"
:key="index"
:item="item"
/>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
},
data() {
return {
items: [...] // 你的数据列表
};
},
mounted() {
this.items.forEach((item) => {
this.$store.dispatch('fetchDictionary', item.id);
this.$store.dispatch('fetchAttachments', item.id);
});
子组件内
// ChildComponent.vue<template>
<!-- 使用计算属性来获取字典数据和附件数据 -->
<div>
<p>Dictionary: {{ dictionaryData }}</p>
<p>Attachments: {{ attachmentsData }}</p>
</div>
</template>
<script>
export default {
props: ['item'],
computed: {
// 使用 getters 来获取字典数据和附件数据
dictionaryData() {
return this.$store.getters.getDictionary(this.item.id);
},
attachmentsData() {
return this.$store.getters.getAttachments(this.item.id);
}
}
};
</script>
以上是 Vue.js中关于EventBus的抽像? 的全部内容, 来源链接: utcz.com/p/934067.html