perf: 暂时还原调整词语高亮组件

This commit is contained in:
rd
2025-09-10 16:04:35 +08:00
parent 48f23cfa02
commit ffed5cb152
2 changed files with 56 additions and 53 deletions

View File

@ -1,15 +1,15 @@
<template>
<div class="highlight-textarea-container">
<TextArea
<a-textarea
ref="textareaWrapRef"
v-model:value="inputValue"
v-model="inputValue"
placeholder="请输入作品描述"
:disabled="disabled"
showCount
:maxlength="1000"
show-word-limit
:max-length="1000"
size="large"
class="textarea-input h-full w-full"
@change="handleInput"
@input="handleInput"
@focus="() => (focus = true)"
@blur="() => (focus = false)"
/>
@ -25,8 +25,7 @@
<script setup lang="ts">
import { Input } from 'ant-design-vue';
import type { ElementEvent } from 'echarts';
const { TextArea } = Input;
const {TextArea} = Input
import { ref, computed, watch, defineProps, defineEmits, onMounted, onUnmounted } from 'vue';
import { escapeRegExp } from './constants';
@ -70,8 +69,7 @@ watch(
);
// 处理输入事件
const handleInput = (e: any) => {
const value = e.currentTarget.value;
const handleInput = (value: string) => {
emit('update:modelValue', value);
};
@ -117,8 +115,8 @@ const generateHighlightedHtml = (): string => {
onMounted(() => {
nativeTextarea =
(textareaWrapRef.value?.$el || textareaWrapRef.value)?.querySelector?.('textarea.ant-input') ||
document.querySelector('.textarea-input .ant-input');
(textareaWrapRef.value?.$el || textareaWrapRef.value)?.querySelector?.('textarea.arco-textarea') ||
document.querySelector('.textarea-input .arco-textarea');
if (nativeTextarea) {
nativeTextarea.addEventListener('scroll', handleTextareaScroll);
@ -147,9 +145,7 @@ const handleTextareaScroll = (e: Event) => {
};
const handleCompositionUpdate = () => {
console.log('handleCompositionUpdate');
if (!nativeTextarea) return;
// 使用 rAF 等待浏览器把最新字符写入 textarea.value 再读取
requestAnimationFrame(() => {
if (!nativeTextarea) return;
@ -203,35 +199,36 @@ const handleCompositionUpdate = () => {
}
}
:deep(.ant-input-textarea) {
:deep(.arco-textarea-wrapper) {
@include textarea-style;
.ant-input {
.arco-textarea {
padding: 0;
overflow: hidden;
position: absolute;
z-index: 1;
width: 100%;
height: 100%;
background: transparent;
color: transparent;
caret-color: #211f24 !important;
resize: none;
@include textarea-padding;
overflow-y: auto;
border: none;
}
}
:deep(.ant-input-data-count) {
.arco-textarea-word-limit {
z-index: 2;
}
&:deep(.ant-input:disabled) {
&.arco-textarea-disabled {
.arco-textarea {
background: #f2f3f5;
}
}
}
// 处于中文输入法合成态时,显示真实文本并隐藏高亮层
:deep(.textarea-input.composing .ant-input) {
:deep(.textarea-input.composing .arco-textarea) {
color: #211f24 !important;
-webkit-text-fill-color: #211f24 !important;
}

View File

@ -1,12 +1,12 @@
<template>
<div class="highlight-textarea-container">
<TextArea
<a-textarea
ref="textareaWrapRef"
v-model:value="inputValue"
v-model="inputValue"
placeholder="请输入作品描述"
:disabled="disabled"
showCount
:maxlength="1000"
show-word-limit
:max-length="1000"
size="large"
class="textarea-input h-full w-full"
@input="handleInput"
@ -25,7 +25,7 @@
<script setup lang="ts">
import { Input } from 'ant-design-vue';
const { TextArea } = Input;
const {TextArea} = Input
import { ref, computed, watch, defineProps, defineEmits, onMounted, onUnmounted } from 'vue';
import { escapeRegExp } from './constants';
@ -52,6 +52,7 @@ const emit = defineEmits<{
// 内部状态管理
const inputValue = ref(props.modelValue || '');
const scrollTop = ref(0);
const focus = ref(false);
const textareaWrapRef = ref();
let nativeTextarea: HTMLTextAreaElement | null = null;
@ -114,8 +115,8 @@ const generateHighlightedHtml = (): string => {
onMounted(() => {
nativeTextarea =
(textareaWrapRef.value?.$el || textareaWrapRef.value)?.querySelector?.('textarea.ant-input') ||
document.querySelector('.textarea-input .ant-input');
(textareaWrapRef.value?.$el || textareaWrapRef.value)?.querySelector?.('textarea.arco-textarea') ||
document.querySelector('.textarea-input .arco-textarea');
if (nativeTextarea) {
nativeTextarea.addEventListener('scroll', handleTextareaScroll);
@ -198,8 +199,10 @@ const handleCompositionUpdate = () => {
}
}
:deep(.ant-input) {
:deep(.arco-textarea-wrapper) {
@include textarea-style;
.arco-textarea {
padding: 0;
overflow: hidden;
position: absolute;
@ -213,16 +216,19 @@ const handleCompositionUpdate = () => {
overflow-y: auto;
}
:deep(.ant-input-data-count) {
.arco-textarea-word-limit {
z-index: 2;
}
&:deep(.ant-input:disabled) {
&.arco-textarea-disabled {
.arco-textarea {
background: #f2f3f5;
}
}
}
// 处于中文输入法合成态时,显示真实文本并隐藏高亮层
:deep(.textarea-input.composing .ant-input) {
:deep(.textarea-input.composing .arco-textarea) {
color: #211f24 !important;
-webkit-text-fill-color: #211f24 !important;
}