From d4d9d8f82c00fe1d24e174e933dc5a902949281c Mon Sep 17 00:00:00 2001
From: rd <1344903914@qq.com>
Date: Wed, 13 Aug 2025 15:57:27 +0800
Subject: [PATCH 1/2] =?UTF-8?q?style:=20=E4=BF=AE=E6=94=B9=E8=83=8C?=
=?UTF-8?q?=E6=99=AF=E8=89=B2?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../check/components/content-card/highlight-textarea.vue | 2 +-
.../check/components/content-card/highlight-textarea.vue | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/views/creative-generation-workshop/manuscript-writer/check/components/content-card/highlight-textarea.vue b/src/views/creative-generation-workshop/manuscript-writer/check/components/content-card/highlight-textarea.vue
index 9dce8c2..e0b3d48 100644
--- a/src/views/creative-generation-workshop/manuscript-writer/check/components/content-card/highlight-textarea.vue
+++ b/src/views/creative-generation-workshop/manuscript-writer/check/components/content-card/highlight-textarea.vue
@@ -189,7 +189,7 @@ const handleTextareaScroll = (e: Event) => {
}
&.arco-textarea-disabled {
.arco-textarea {
- background: #f5f5f5;
+ background: #f2f3f5;
}
}
}
diff --git a/src/views/creative-generation-workshop/manuscript/check/components/content-card/highlight-textarea.vue b/src/views/creative-generation-workshop/manuscript/check/components/content-card/highlight-textarea.vue
index aceb257..7956d24 100644
--- a/src/views/creative-generation-workshop/manuscript/check/components/content-card/highlight-textarea.vue
+++ b/src/views/creative-generation-workshop/manuscript/check/components/content-card/highlight-textarea.vue
@@ -190,7 +190,7 @@ const handleTextareaScroll = (e: Event) => {
}
&.arco-textarea-disabled {
.arco-textarea {
- background: #f5f5f5;
+ background: #f2f3f5;
}
}
}
From 930051a39c867efec9dff9f759f7c4b7f74739b7 Mon Sep 17 00:00:00 2001
From: rd <1344903914@qq.com>
Date: Wed, 13 Aug 2025 16:33:01 +0800
Subject: [PATCH 2/2] =?UTF-8?q?feat:=20textarea=E9=AB=98=E4=BA=AE=E8=AF=8D?=
=?UTF-8?q?=E8=AF=AD=E7=BB=84=E4=BB=B6=E8=B0=83=E6=95=B4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../content-card/highlight-textarea.vue | 78 ++++++++++++-------
.../content-card/highlight-textarea.vue | 74 +++++++++++-------
2 files changed, 98 insertions(+), 54 deletions(-)
diff --git a/src/views/creative-generation-workshop/manuscript-writer/check/components/content-card/highlight-textarea.vue b/src/views/creative-generation-workshop/manuscript-writer/check/components/content-card/highlight-textarea.vue
index e0b3d48..c02dbf5 100644
--- a/src/views/creative-generation-workshop/manuscript-writer/check/components/content-card/highlight-textarea.vue
+++ b/src/views/creative-generation-workshop/manuscript-writer/check/components/content-card/highlight-textarea.vue
@@ -1,24 +1,11 @@
-
(focus = true)"
- @blur="() => (focus = false)"
- />
+ (focus = true)" @blur="() => (focus = false)" />
-
+
@@ -47,9 +34,11 @@ const emit = defineEmits<{
(e: 'update:modelValue', value: string): void;
}>();
+// 内部状态管理
const inputValue = ref(props.modelValue || '');
-const scrollTop = ref(0);
const focus = ref(false);
+const textareaWrapRef = ref();
+let nativeTextarea: HTMLTextAreaElement | null = null;
const highlightedHtml = computed(() => generateHighlightedHtml());
// 监听外部modelValue变化
@@ -67,12 +56,6 @@ const handleInput = (value: string) => {
emit('update:modelValue', value);
};
-// 同步滚动位置
-const syncScroll = (e: Event) => {
- console.log('syncScroll');
- scrollTop.value = (e.target as HTMLTextAreaElement).scrollTop;
-};
-
const escapeHtml = (str: string): string => {
if (!isString(str)) return '';
return str
@@ -114,11 +97,24 @@ const generateHighlightedHtml = (): string => {
};
onMounted(() => {
- document.querySelector('.textarea-input .arco-textarea')?.addEventListener('scroll', handleTextareaScroll);
+ nativeTextarea = (textareaWrapRef.value?.$el || textareaWrapRef.value)?.querySelector?.('textarea.arco-textarea') ||
+ document.querySelector('.textarea-input .arco-textarea');
+
+ if (nativeTextarea) {
+ nativeTextarea.addEventListener('scroll', handleTextareaScroll);
+ nativeTextarea.addEventListener('compositionstart', handleCompositionUpdate);
+ nativeTextarea.addEventListener('compositionupdate', handleCompositionUpdate);
+ nativeTextarea.addEventListener('compositionend', handleCompositionUpdate);
+ }
});
onUnmounted(() => {
- document.querySelector('.textarea-input .arco-textarea')?.removeEventListener('scroll', handleTextareaScroll);
+ if (nativeTextarea) {
+ nativeTextarea.removeEventListener('scroll', handleTextareaScroll);
+ nativeTextarea.removeEventListener('compositionstart', handleCompositionUpdate);
+ nativeTextarea.removeEventListener('compositionupdate', handleCompositionUpdate);
+ nativeTextarea.removeEventListener('compositionend', handleCompositionUpdate);
+ }
});
const handleTextareaScroll = (e: Event) => {
@@ -129,6 +125,18 @@ const handleTextareaScroll = (e: Event) => {
highlightElement.scrollTop = _scrollTop;
}
};
+
+const handleCompositionUpdate = () => {
+ if (!nativeTextarea) return;
+ // 使用 rAF 等待浏览器把最新字符写入 textarea.value 再读取
+ requestAnimationFrame(() => {
+ if (!nativeTextarea) return;
+ const latest = nativeTextarea.value.slice(0, 1000);
+ if (latest !== inputValue.value) {
+ inputValue.value = latest;
+ }
+ });
+};
diff --git a/src/views/creative-generation-workshop/manuscript/check/components/content-card/highlight-textarea.vue b/src/views/creative-generation-workshop/manuscript/check/components/content-card/highlight-textarea.vue
index 7956d24..3644d31 100644
--- a/src/views/creative-generation-workshop/manuscript/check/components/content-card/highlight-textarea.vue
+++ b/src/views/creative-generation-workshop/manuscript/check/components/content-card/highlight-textarea.vue
@@ -1,24 +1,11 @@
-
(focus = true)"
- @blur="() => (focus = false)"
- />
+ (focus = true)" @blur="() => (focus = false)" />
-
+
@@ -51,6 +38,8 @@ const emit = defineEmits<{
const inputValue = ref(props.modelValue || '');
const scrollTop = ref(0);
const focus = ref(false);
+const textareaWrapRef = ref();
+let nativeTextarea: HTMLTextAreaElement | null = null;
const highlightedHtml = computed(() => generateHighlightedHtml());
// 监听外部modelValue变化
@@ -68,12 +57,6 @@ const handleInput = (value: string) => {
emit('update:modelValue', value);
};
-// 同步滚动位置
-const syncScroll = (e: Event) => {
- console.log('syncScroll');
- scrollTop.value = (e.target as HTMLTextAreaElement).scrollTop;
-};
-
const escapeHtml = (str: string): string => {
if (!isString(str)) return '';
return str
@@ -115,11 +98,24 @@ const generateHighlightedHtml = (): string => {
};
onMounted(() => {
- document.querySelector('.textarea-input .arco-textarea')?.addEventListener('scroll', handleTextareaScroll);
+ nativeTextarea = (textareaWrapRef.value?.$el || textareaWrapRef.value)?.querySelector?.('textarea.arco-textarea') ||
+ document.querySelector('.textarea-input .arco-textarea');
+
+ if (nativeTextarea) {
+ nativeTextarea.addEventListener('scroll', handleTextareaScroll);
+ nativeTextarea.addEventListener('compositionstart', handleCompositionUpdate);
+ nativeTextarea.addEventListener('compositionupdate', handleCompositionUpdate);
+ nativeTextarea.addEventListener('compositionend', handleCompositionUpdate);
+ }
});
onUnmounted(() => {
- document.querySelector('.textarea-input .arco-textarea')?.removeEventListener('scroll', handleTextareaScroll);
+ if (nativeTextarea) {
+ nativeTextarea.removeEventListener('scroll', handleTextareaScroll);
+ nativeTextarea.removeEventListener('compositionstart', handleCompositionUpdate);
+ nativeTextarea.removeEventListener('compositionupdate', handleCompositionUpdate);
+ nativeTextarea.removeEventListener('compositionend', handleCompositionUpdate);
+ }
});
const handleTextareaScroll = (e: Event) => {
@@ -130,6 +126,18 @@ const handleTextareaScroll = (e: Event) => {
highlightElement.scrollTop = _scrollTop;
}
};
+
+const handleCompositionUpdate = () => {
+ if (!nativeTextarea) return;
+ // 使用 rAF 等待浏览器把最新字符写入 textarea.value 再读取
+ requestAnimationFrame(() => {
+ if (!nativeTextarea) return;
+ const latest = nativeTextarea.value.slice(0, 1000);
+ if (latest !== inputValue.value) {
+ inputValue.value = latest;
+ }
+ });
+};