refactor(editor): 优化mention处理逻辑并移除调试日志

移除调试用的console.log语句
重构mention列表过滤逻辑,使用startsWith替代includes
添加Backspace和Delete键删除mention元素的功能
优化键盘事件处理逻辑,减少不必要的DOM操作
This commit is contained in:
Phoenix 2025-06-09 13:57:15 +08:00
parent 047cea20b9
commit 628894a254
2 changed files with 122 additions and 10 deletions

View File

@ -33,7 +33,6 @@ const props = defineProps({
const emit = defineEmits(['editor-event'])
//
const editorRef = ref(null)
const content = ref('')
const isFocused = ref(false)
@ -49,7 +48,6 @@ const fileImageRef = ref(null)
const uploadFileRef = ref(null)
const emoticonRef = ref(null)
//
const dialogueStore = useDialogueStore()
const editorDraftStore = useEditorDraftStore()
@ -94,7 +92,7 @@ const toolbarConfig = computed(() => {
return config
})
// - DOM
//
const handleInput = (event) => {
const target = event.target
@ -162,9 +160,9 @@ const checkMention = (target) => {
// mention
const showMentionList = () => {
const query = currentMentionQuery.value.toLowerCase()
mentionList.value = props.members.filter(member =>
member.nickname.toLowerCase().includes(query)
).slice(0, 10)
mentionList.value = props.members.filter(member => {
return member.value.toLowerCase().startsWith(query)
})
showMention.value = mentionList.value.length > 0
selectedMentionIndex.value = 0
@ -310,7 +308,7 @@ const handlePaste = (event) => {
}
}
// -
//
const handleKeydown = (event) => {
// @
if (showMention.value) {
@ -358,6 +356,122 @@ const handleKeydown = (event) => {
return
}
// BackspaceDeletemention
if (event.key === 'Backspace' || event.key === 'Delete') {
const selection = window.getSelection()
if (!selection.rangeCount) return
const range = selection.getRangeAt(0)
const editor = editorRef.value
//
if (range.collapsed) {
let targetMention = null
//
const container = range.startContainer
const offset = range.startOffset
if (event.key === 'Backspace') {
// Backspacemention
if (container.nodeType === Node.TEXT_NODE) {
//
if (offset === 0) {
let prevSibling = container.previousSibling
while (prevSibling) {
if (prevSibling.nodeType === Node.ELEMENT_NODE &&
prevSibling.classList &&
prevSibling.classList.contains('mention')) {
targetMention = prevSibling
break
}
//
if (prevSibling.nodeType === Node.TEXT_NODE && prevSibling.textContent.trim()) {
break
}
prevSibling = prevSibling.previousSibling
}
}
} else if (container.nodeType === Node.ELEMENT_NODE) {
//
if (offset > 0) {
let prevChild = container.childNodes[offset - 1]
// mention
if (prevChild && prevChild.nodeType === Node.ELEMENT_NODE &&
prevChild.classList && prevChild.classList.contains('mention')) {
targetMention = prevChild
}
//
else if (prevChild && prevChild.nodeType === Node.TEXT_NODE && !prevChild.textContent.trim()) {
let prevSibling = prevChild.previousSibling
while (prevSibling) {
if (prevSibling.nodeType === Node.ELEMENT_NODE &&
prevSibling.classList &&
prevSibling.classList.contains('mention')) {
targetMention = prevSibling
break
}
if (prevSibling.nodeType === Node.TEXT_NODE && prevSibling.textContent.trim()) {
break
}
prevSibling = prevSibling.previousSibling
}
}
} else if (offset === 0 && container === editor) {
// mention
const firstChild = container.firstChild
if (firstChild && firstChild.nodeType === Node.ELEMENT_NODE &&
firstChild.classList && firstChild.classList.contains('mention')) {
targetMention = firstChild
}
}
}
} else if (event.key === 'Delete') {
// Deletemention
if (container.nodeType === Node.TEXT_NODE) {
//
if (offset === container.textContent.length) {
let nextSibling = container.nextSibling
while (nextSibling) {
if (nextSibling.nodeType === Node.ELEMENT_NODE &&
nextSibling.classList &&
nextSibling.classList.contains('mention')) {
targetMention = nextSibling
break
}
//
if (nextSibling.nodeType === Node.TEXT_NODE && nextSibling.textContent.trim()) {
break
}
nextSibling = nextSibling.nextSibling
}
}
} else if (container.nodeType === Node.ELEMENT_NODE) {
//
if (offset < container.childNodes.length) {
const nextChild = container.childNodes[offset]
if (nextChild && nextChild.nodeType === Node.ELEMENT_NODE &&
nextChild.classList && nextChild.classList.contains('mention')) {
targetMention = nextChild
}
}
}
}
// mention
if (targetMention) {
event.preventDefault()
// mention
targetMention.remove()
//
handleInput({ target: editor })
return
}
}
}
// Ctrl+EnterShift+Enter
if (event.key === 'Enter' && (event.ctrlKey || event.metaKey || event.shiftKey)) {
//
@ -402,7 +516,7 @@ const handleKeydown = (event) => {
}
}
// -
//
const sendMessage = () => {
//
const messageData = parseEditorContent()

View File

@ -16,8 +16,6 @@ import avatarModule from '@/components/avatar-module/index.vue'
const userStore = useUserStore()
const dialogueStore = useDialogueStore()
const uploadsStore = useUploadsStore()
console.log('dialogueStore', dialogueStore)
const members = computed(() => dialogueStore.members)
const membersByAlphabet = computed(() => {
if (state.searchMemberByAlphabet) {