文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
互访 Store
新建一个模型类,代码如下所示:
src/model/ModelMessage.ts
import { ModalBase } from './ModalBase';
export class ModelMessage extends ModalBase {
createTime?: number;
receiveTime?: number;
messageContent?: string;
chatId?: string;
fromName?: string;
avatar?: string;
// 是否为传入消息
isInMsg?: boolean;
}
创建 useMessageStore,用于管理消息的状态数据,代码如下:
src/renderer/store/useMessageStore.ts
import { ModelChat } from '../../model/ModelChat';
import { ModelMessage } from '../../model/ModelMessage';
import { defineStore } from 'pinia';
import { ref, Ref } from 'vue';
export const useMessageStore = defineStore('message', () => {
let data: Ref<ModelMessage[]> = ref([]);
const msg1 = `醉里挑灯看剑,梦回吹角连营。八百里分麾下灸,五十弦翻塞外声。沙场秋点兵。马作的卢飞快,弓如霹雳弦惊。了却君王天下事,嬴得生前身后名。可怜白发生`;
const msg2 = `怒发冲冠,凭栏处,潇潇雨歇。抬望眼,仰天长啸,壮怀激烈。 三十功名尘与土,八千里路云和月。莫等闲,白了少年头,空悲切! 靖康耻,犹未雪;臣子恨,何时灭?驾长车,踏破贺兰山缺! 壮志饥餐胡虏肉,笑谈渴饮匈奴血。待从头,收拾旧山河,朝天阙!`;
const initData = (chat: ModelChat) => {
let result = [];
for (let i = 0; i < 10; i++) {
let model = new ModelMessage();
model.createTime = Date.now();
model.isInMsg = i % 2 === 0;
model.messageContent = model.isInMsg ? msg1 : msg2;
model.fromName = model.isInMsg ? chat.fromName : "我";
model.avatar = chat.avatar;
model.chatId = chat.id;
result.push(model);
}
data.value = result;
};
return { data, initData };
});
消息数据是模拟出来的,这里模拟了 10 条消息,预期用户切换会话的时候,执行 initData 方法,初始化当前会话的消息。
修改一下 MessageBoard 组件的的代码,如下所示:
src/renderer/window/WindowMain/chat/components/MessageBoard.vue
<template>
<div class="MessageBord">
<BarTop />
<div class="MessageList">
<MessageItem :data="item" v-for="item in messageStore.data" :key="item.id"></MessageItem>
</div>
</div>
</template>
<script lang="ts" setup>
import BarTop from '../../../../components/BarTop.vue';
import { ModelChat } from '../../../../../model/ModelChat';
import { useMessageStore } from '../../../../store/useMessageStore';
import { useChatStore } from '../../../../store/useChatStore';
import MessageItem from './MessageItem.vue';
const chatStore = useChatStore();
const messageStore = useMessageStore();
let curId = '';
chatStore.$subscribe((mutations, state) => {
const item = state.data.find(v => v.isSelected) as ModelChat;
if (item?.id !== curId) {
messageStore.initData(item);
curId = item?.id;
}
})
</script>
<style scoped lang="scss">
.MessageBord {
height: 100%;
display: flex;
flex: 1;
flex-direction: column;
}
.MessageList {
flex: 1;
overflow-y: auto;
overflow-x: hidden;
background: rgb(245, 245, 245);
}
</style>
当选中的聊天会话切换时,执行 messageStore 对象的 initData 方法,这样就初始化了 messageStore 内部的状态数据。
MessageItem 是新创建的一个 Vue 组件,这个组件用于显示一条消息的具体信息。代码如下所示:
src/renderer/window/WindowMain/chat/components/MessageItem.vue
<template>
<template v-if="data.isInMsg">
<div class="MessageItem left">
<div class="avatar">
<img :src="data.avatar" alt="" />
</div>
<div class="MessageBox">
<div class="FromName">{{ data.fromName }}</div>
<div class="MsgContent">{{ data.messageContent }}</div>
</div>
</div>
</template>
<template v-else>
<div class="MessageItem right">
<div class="MessageBox">
<div class="MessageContent">{{ data.messageContent }}</div>
</div>
<div class="avatar">
<img :src="data.avatar" alt="" />
</div>
</div>
</template>
</template>
<script setup lang="ts">
import { ModelMessage } from '../../../../../model/ModelMessage';
defineProps<{ data: ModelMessage }>();
</script>
<style lang="scss" scoped>
.MessageItem {
display: flex;
padding-top: 8px;
padding-bottom: 8px;
position: relative;
}
.left {
padding-right: 30%;
&::after {
width: 0;
height: 0;
border-top: 6px solid transparent;
border-bottom: 6px solid transparent;
border-right: 6px solid #fff;
position: absolute;
left: 60px;
top: 38px;
content: "";
}
}
.right {
padding-left: 30%;
&::after {
width: 0;
height: 0;
border-top: 6px solid transparent;
border-bottom: 6px solid transparent;
border-left: 6px solid rgb(149, 236, 105);
position: absolute;
right: 60px;
top: 18px;
content: "";
}
.MessageContent {
background: rgb(149, 236, 105) !important;
}
}
.avatar {
width: 66px;
text-align: center;
img {
width: 46px;
height: 46px;
}
}
.MessageBox {
flex: 1;
}
.FromName {
color: rgb(178, 178, 178);
margin-bottom: 6px;
}
.MessageContent {
background: #fff;
border-radius: 3px;
padding: 8px;
line-height: 22px;
}
</style>
在切换选中的聊天会话时,直接初始化 messageStore 里的数据,就完全不需要在 MessageBord 组件里订阅 chatStore 的数据变更了。
pinia 是支持这种操作的,现在修改一下 useChatStore 的代码,如下所示:
import { defineStore } from 'pinia';
import { Ref, ref } from 'vue';
import { ModelChat } from '../../model/ModelChat';
import { useMessageStore } from './useMessageStore';
// mock data
const prepareData = () => {
let result = [];
for (let i = 0; i < 10; i++) {
let model = new ModelChat();
model.fromName = '聊天对象' + i;
model.sendTime = '昨天';
model.lastMsg = '这是此会话的最后一条消息' + i;
model.avatar = 'https://pic3.zhimg.com/v2-306cd8f07a20cba46873209739c6395d_im.jpg?source=32738c0c';
result.push(model);
}
return result;
};
export const useChatStore = defineStore('chat', () => {
let data: Ref<ModelChat[]> = ref(prepareData());
const selectItem = (item: ModelChat) => {
if (item.isSelected) return;
data.value.forEach((v) => (v.isSelected = false));
item.isSelected = true;
const messageStore = useMessageStore();
messageStore.initData(item);
};
return { data, selectItem };
});
在 selectItem 方法内使用 messageStore 提供的方法。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论