如何在Vue 3中编排悬念组件和Vuex的异步依赖关系?



我试图使用Vue 3悬念组件为我的APP,但所有的例子,我发现加载组件内的异步数据,在我的情况下,我从WebSocket获得所有的数据,然后使用Vuex模块注入该数据在我的APP通过getter。

基本上,WebSocket发送聊天记录,然后我使用来自Vuex模块的动作和突变将这些聊天记录存储在数组中,然后我使用getter将聊天记录数组暴露给我的APP。

这是处理WebSocket的vuex模块,我只是添加代码来获取聊天,只要WebSocket从后端发送消息。正如你所看到的,我正在使用getter来将传入的chats数组公开给我的APP。

export const state = {
connected: false,
error: null,
connectionId: "",
incomingChats: [],
socket: {},
};
export const actions = {
async processWebsocket({ dispatch, rootState, commit }) {
const socket = await new WebSocket(settings.MY_WEBSOCKET);
socket.onmessage = function (event) {
const socketData = JSON.parse(event.data);
const socketDataType = socketData.type;
if (
socketData.connectionId &&
socketData.connectionId !== state.connectionId
) {
commit("SET_CONNECTION_ID", socketData.connectionId);
dispatch("shifts/updateEventsSubscription", rootState.token.agentId, {
root: true,
});
} else {
switch (socketDataType) {
case "incoming-chats-updated":
dispatch("setIncomingChats", socketData.incomingChats);
break;
}
}
}
};
},
async setIncomingChats({ commit }, incomingChats) {
commit("SET_INCOMING_CHATS", incomingChats);
},
};
export const mutations = {
SET_INCOMING_CHATS(state, incomingChats) {
state.incomingChats = incomingChats;
},
};
export const getters = {
getIncomingChats: (state) => {
return state.incomingChats;
},
};

那么这就是我试图使用悬念的部分。基本上是一个父组件(聊天队列),它将绘制来自websocket的聊天(BaseChat组件):

<template>
<div>
<Suspense>
<template #default>
<ul class="overflow-y-auto pr-2">
<BaseChat
v-for="(chat, index) in incomingChats"
:key="index"
:chat="chat"
:class="{ 'mt-0': index === 0, 'mt-4': index > 0 }"
@click="assigningChatToAgent(chat.id)"
/>
</ul>
</template>
<template #fallback> Loading Article </template>
</Suspense>
</div>
</template>
<script>
import { useGetters, useActions } from "vuex-composition-helpers";
import BaseChat from "@/components/BaseChat.vue";
import ChatService from "@/services/ChatService.js";
export default {
components: {
BaseChat,
},
setup() {
const { incomingChats, agentId } = useGetters({
incomingChats: "websocket/getIncomingChats",
agentId: "token/getAgentId",
});
const { addChatSession } = useActions({
addChatSession: "chatSession/addChatSession",
});
function assigningChatToAgent(chatId) {
const agentIdValue = JSON.parse(JSON.stringify(agentId.value));
const assignChatObject = {
aggregateId: chatId,
agentId: agentIdValue.agentId,
};
ChatService.assignChatToAgent(assignChatObject);
}
return {
incomingChats,
agentId,
addChatSession,
assigningChatToAgent,
};
},
};
</script>   

我知道我必须创建一个异步设置函数,然后等待一个承诺来解决,但我只是不知道如何做到这一点,因为我应该等待一个getter从我的vuex模块来解决,所有的例子,我发现做父组件内(他们从组件内获取数据)。

这里的另一个特殊之处在于我使用了" vex -composition-helpers"为了使用getter和action,我不知道这是否会影响悬念的实现方式。

最理想的情况是APP在显示"incomingChats"Getter未解析。非常感谢您的帮助。

我创建了HOC,它帮助我减少了样本文件,您可以在setup函数中使用async操作(不要忘记设置为async),然后在生成导入时包装您的组件:

const withSuspense = (
Component,
SuspenseComponent,
skeletonProps
) => {
return defineComponent({
components: {
SuspenseComponent
},
setup() {
return (instance) =>
h(Suspense, null, {
fallback: () => h(SuspenseComponent, skeletonProps),
default: () =>
h(Component, { ...instance.$attrs }, { ...instance.$slots })
});
}
});
};

然后换行:

export default withSuspense(YourComponent, Skeleton, skeletonProps);

示例:https://stackblitz.com/edit/vue-zmfbaz

最新更新