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.js

import 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.js

import 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

回到顶部