From 025ce0de9f669e6d4a4b062079000307c1fbf5c1 Mon Sep 17 00:00:00 2001 From: WangLeo <690854599@qq.com> Date: Tue, 9 Jun 2026 16:03:12 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=BB=9A=E5=8A=A8?= =?UTF-8?q?=E6=97=B6=E8=BE=93=E5=85=A5=E6=A1=86=E8=A1=8C=E6=95=B0=E4=B8=8D?= =?UTF-8?q?=E6=94=B6=E7=BC=A9=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根因:Element Plus 的 ElInput 不支持 autosize prop 动态更新 — 只在 mount 时读取, prop 变化后不会重新计算 textarea 高度。dialogBox 重构时去掉了 Sender 的 :key, 导致 Sender_variant 切换后 ElInput 保持初始行数不变。 修复:恢复 Sender 的 :key="useDisplay.Sender_variant",variant 切换时强制重挂载, 使 ElInput 以正确的 minRows/maxRows 初始化。 CLAUDE.md 补充:VirtualScroller 坐标系统映射表、输入框滚动收缩完整链路、 Element Plus autosize 非响应式陷阱。 --- CLAUDE.md | 30 ++++++++++++++++++++++++++++++ src/components/dialogBox/index.vue | 1 + 2 files changed, 31 insertions(+) diff --git a/CLAUDE.md b/CLAUDE.md index ba597f8..2f54f6d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -186,6 +186,36 @@ Painting 模型参数 schema 在 `src/platforms/painting/models/*.js` 中,参 - **模型列表缓存**:`modelApi.js` 中 `fetchPlatformModels` 使用 localStorage 30 秒 TTL + `pendingRequests` Map 并发去重。 - **平台包预加载**:dialogBox 顶层 `import` Painting 和 Video 平台包,触发自注册,确保首次使用时 registry 已就绪。 - **VirtualScroller 反旋转**:组件用外层 `transform: rotate(180deg)` 实现 reverse 底部锚定。所有作为 slot 插入的内容必须在根元素加 `transform: rotate(180deg)` 反旋转,否则文字/图片会颠倒显示。参考 `src/views/home/display/components/set.vue:2`。 +- **VirtualScroller 存在独立测试页**:`src/components/virtual-scroller/test.html` + `test-data.js`,可用于验证虚拟滚动行为。 +- **Element Plus `` 不响应 `autosize` 动态变化**:`ElInput` 只在 mount 时读取 `autosize`,prop 更新时不会重新计算高度。因此 `dialogBox` 中 `Sender` 必须绑定 `:key="useDisplay.Sender_variant"`,通过强制重挂载来使新的 `autosize`(`minRows`/`maxRows`)生效。 + +### VirtualScroller 坐标系统 + +`VirtualScroller` 使用 180deg 旋转实现 reverse 模式。`handleScroll` 内部将容器物理坐标映射为"页面逻辑坐标"后通过 `emit('scroll', {...})` 发出: + +| 字段 | 计算 | 含义 | +|------|------|------| +| `distanceToPageTop` | `scrollHeight - scrollTop - clientHeight` | 距离页面**顶部**(旧内容端)的距离 | +| `distanceToPageBottom` | `scrollTop` | 距离页面**底部**(新内容端)的距离 | +| `isAtPageTop` | `distanceToPageTop <= 0` | 滚动到页面最顶部 | +| `isAtPageBottom` | `distanceToPageBottom <= 0` | 滚动到页面最底部 | + +**注意**:`distanceToPageBottom = scrollTop`(不是 `distanceToPageTop`),表示从底部向上滚动的距离。判断"用户向上滚动了多少"应使用此字段。 + +### 输入框滚动收缩机制 + +滚动列表时提示词输入框自动收缩为一行,这是跨 4 个文件的响应式链路: + +1. `VirtualScroller` 发出 `scroll` 事件(含 `isAtPageBottom`、`distanceToPageBottom` 等) +2. `display/index.vue` 的 `handleScroll` 根据滚动位置切换 `useDisplay.Sender_variant`: + - `isAtPageBottom`(底部)→ `'updown'`(展开,5-9 行) + - `distanceToPageBottom >= 350`(已滚离底部 350px)→ `'default'`(收缩,1 行) + - 中间状态 → `'updown'`(展开) +3. `display.js` store 中 `Sender_variant` 是响应式 ref +4. `dialogBox/index.vue` 的 `autoSizeConfig` 计算属性读取 `Sender_variant`,返回 `{ minRows, maxRows }` +5. `Sender` 组件通过 `:key="useDisplay.Sender_variant"` **强制重挂载**(因为 Element Plus `ElInput` 不支持 `autosize` 动态更新),新实例以正确的行数初始化 + +滚动阈值 350px 对应 `VirtualScroller` 的 `bottomPlaceholderHeight`。 ### 接口速查 diff --git a/src/components/dialogBox/index.vue b/src/components/dialogBox/index.vue index ebe51d2..c66abdd 100644 --- a/src/components/dialogBox/index.vue +++ b/src/components/dialogBox/index.vue @@ -23,6 +23,7 @@