fix:完善评论组件@圈人功能
This commit is contained in:
@@ -2,35 +2,40 @@
|
||||
<div class="comment-app">
|
||||
<section class="main-publisher">
|
||||
<div class="input-wrapper">
|
||||
<el-input
|
||||
v-model="mainInput"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
:placeholder="t('comment.placeholder')"
|
||||
resize="none"
|
||||
/>
|
||||
<div class="input-tools">
|
||||
<div class="left-icons">
|
||||
<!-- 提到-后续迭代 -->
|
||||
<!-- <el-button link title="提到">@</el-button> -->
|
||||
<!-- 图片功能-后续迭代 -->
|
||||
<!-- <el-button link title="图片"><el-icon><Picture /></el-icon></el-button> -->
|
||||
<!-- 附件功能-后续迭代 -->
|
||||
<!-- <el-button link title="附件"><el-icon><Paperclip /></el-icon></el-button> -->
|
||||
|
||||
<!-- 表情功能 -->
|
||||
<emoji-picker @select="(e) => onSelectEmoji(e, 'main')" />
|
||||
<mentionEditor v-model="mainInput" :users="userList" @select="onUserMentioned">
|
||||
<el-input
|
||||
v-model="mainInput"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
:placeholder="t('comment.placeholder')"
|
||||
resize="none"
|
||||
/>
|
||||
</mentionEditor>
|
||||
<div class="input-tools">
|
||||
<div class="left-icons">
|
||||
<!-- 提到-后续迭代 -->
|
||||
<!-- <el-button link title="提到">@</el-button> -->
|
||||
<!-- 图片功能-后续迭代 -->
|
||||
<!-- <el-button link title="图片"><el-icon><Picture /></el-icon></el-button> -->
|
||||
<!-- 附件功能-后续迭代 -->
|
||||
<!-- <el-button link title="附件"><el-icon><Paperclip /></el-icon></el-button> -->
|
||||
|
||||
<!-- 表情功能 -->
|
||||
<emoji-picker @select="(e) => onSelectEmoji(e, 'main')" />
|
||||
</div>
|
||||
<el-divider direction="vertical" />
|
||||
<el-button
|
||||
class="send-btn"
|
||||
type="primary"
|
||||
link
|
||||
@click="submitMainComment"
|
||||
>
|
||||
<el-icon :size="20" :title="t('comment.send')"
|
||||
><Promotion
|
||||
/></el-icon>
|
||||
</el-button>
|
||||
</div>
|
||||
<el-divider direction="vertical" />
|
||||
<el-button
|
||||
class="send-btn"
|
||||
type="primary"
|
||||
link
|
||||
@click="submitMainComment"
|
||||
>
|
||||
<el-icon :size="20" :title="t('comment.send')"><Promotion /></el-icon>
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -127,7 +132,7 @@
|
||||
</div>
|
||||
<span class="time">{{ formatTime(reply.time) }}</span>
|
||||
</div>
|
||||
<div class="content-body">{{ reply.content }}</div>
|
||||
<div class="content-body" v-html="parseMention(reply.content)"></div>
|
||||
<!-- 回复 删除功能 -->
|
||||
<div class="actions">
|
||||
<el-button link @click="openReply(item, item)">
|
||||
@@ -153,13 +158,17 @@
|
||||
class="inline-publisher"
|
||||
>
|
||||
<div class="input-wrapper">
|
||||
<mentionEditor v-model="replyInput" :users="userList" @select="onUserMentioned">
|
||||
<el-input
|
||||
v-model="replyInput"
|
||||
:placeholder="`${t('comment.reply')} @${activeReply.targetName}...`"
|
||||
:placeholder="`${t('comment.reply')} @${
|
||||
activeReply.targetName
|
||||
}...`"
|
||||
type="textarea"
|
||||
:autosize="{ minRows: 2, maxRows: 4 }"
|
||||
resize="none"
|
||||
/>
|
||||
</mentionEditor>
|
||||
<div class="input-tools">
|
||||
<div class="left-icons">
|
||||
<!-- 表情功能 -->
|
||||
@@ -174,7 +183,9 @@
|
||||
link
|
||||
@click="submitReply"
|
||||
>
|
||||
<el-icon :size="20" :title="t('comment.send')"><Promotion /></el-icon>
|
||||
<el-icon :size="20" :title="t('comment.send')"
|
||||
><Promotion
|
||||
/></el-icon>
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -194,8 +205,9 @@ import EmojiPicker from "./EmojiPicker.vue";
|
||||
import NameAvatar from "@/components/nameAvatar/index.vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useUserStore } from "@/store";
|
||||
import { useRelativeTime } from '@/hooks/useRelativeTime'
|
||||
const { formatTime } = useRelativeTime()
|
||||
import { useRelativeTime } from "@/hooks/useRelativeTime";
|
||||
import mentionEditor from "./mentionEditor.vue";
|
||||
const { formatTime } = useRelativeTime();
|
||||
const userStore = useUserStore();
|
||||
const { t } = useI18n();
|
||||
// 当前用户信息
|
||||
@@ -272,47 +284,60 @@ const cancelReply = () => {
|
||||
activeReply.groupId = null;
|
||||
};
|
||||
|
||||
// @ 识别解析函数
|
||||
const parseMention = (text) => {
|
||||
if (!text) return "";
|
||||
// 基础转义
|
||||
let safeText = text.replace(/</g, "<").replace(/>/g, ">");
|
||||
// 正则匹配 @用户,包裹为 span
|
||||
return safeText.replace(
|
||||
/@([\u4e00-\u9fa5\w-]+)/g,
|
||||
'<span class="mention-link">@$1</span>'
|
||||
);
|
||||
};
|
||||
// @提及 圈人操作
|
||||
const handleMentionAction = (name) => {
|
||||
const mentionStr = typeof name === "string" ? `@${name} ` : "@";
|
||||
mainInput.value += mentionStr;
|
||||
// @圈人的操作
|
||||
const userList = [
|
||||
{ id: 1, nickname: "李星倩" },
|
||||
{ id: 2, nickname: "冯娜" },
|
||||
{ id: 3, nickname: "张三" }
|
||||
];
|
||||
|
||||
const onUserMentioned = (user) => {
|
||||
console.log('Mentioned:', user.nickname);
|
||||
};
|
||||
|
||||
const submitMainComment = () => {
|
||||
if (!mainInput.value.trim()) return ElMessage.warning("内容不能为空");
|
||||
|
||||
const formattedContent = mainInput.value.replace(
|
||||
/@([^\s@]+)/g,
|
||||
'<span class="mention-highlight">@$1</span>'
|
||||
);
|
||||
|
||||
commentData.value.unshift({
|
||||
id: Date.now(),
|
||||
...currentUser.value,
|
||||
content: mainInput.value,
|
||||
content: formattedContent,
|
||||
time: new Date().valueOf(),
|
||||
canDelete: true,
|
||||
children: [],
|
||||
});
|
||||
|
||||
mainInput.value = "";
|
||||
};
|
||||
|
||||
const submitReply = () => {
|
||||
const targetGroup = commentData.value.find(
|
||||
(i) => i.id === activeReply.groupId
|
||||
// 通用的内容转换函数
|
||||
const parseMention = (text) => {
|
||||
if (!text) return "";
|
||||
return text.replace(
|
||||
/@([^\s@]+)/g,
|
||||
'<span class="mention-highlight">@$1</span>'
|
||||
);
|
||||
};
|
||||
|
||||
const submitReply = () => {
|
||||
const targetGroup = commentData.value.find(i => i.id === activeReply.groupId);
|
||||
if (targetGroup) {
|
||||
const formattedReply = replyInput.value.replace(
|
||||
/@([^\s@]+)/g,
|
||||
'<span class="mention-highlight">@$1</span>'
|
||||
);
|
||||
|
||||
targetGroup.children.push({
|
||||
id: Date.now(),
|
||||
...currentUser.value,
|
||||
replyTo: activeReply.targetName,
|
||||
content: replyInput.value,
|
||||
time: "刚刚",
|
||||
content: formattedReply, // 使用处理后的 HTML
|
||||
time: new Date().valueOf(),
|
||||
});
|
||||
cancelReply();
|
||||
}
|
||||
@@ -506,6 +531,23 @@ $color-white: #fff;
|
||||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 在 style 标签内添加 */
|
||||
:deep(.mention-highlight) {
|
||||
background-color: rgba(64, 158, 255, 0.1); /* 浅蓝色背景 */
|
||||
color: #409eff; /* 蓝色文字 */
|
||||
padding: 2px 4px;
|
||||
border-radius: 4px;
|
||||
font-weight: 500;
|
||||
margin: 0 2px;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(64, 158, 255, 0.2);
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 评论组件骨架屏
|
||||
|
||||
Reference in New Issue
Block a user