Files
biji/memory-bank/activeContext.md
ikmkj 337645f27b fix(note-editor): 优化自动保存机制,解决切换笔记时的保存问题
- 修复了在切换笔记时意外触发自动保存的问题- 引入标志位区分用户输入和程序加载内容
-优化了自动保存的防抖逻辑,提高用户体验
- 删除了不必要的组件代码,精简结构
2025-08-14 07:49:40 +08:00

56 lines
3.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Bug 分析与修复报告:优化笔记编辑器自动保存机制
**日期:** 2025-08-13
**作者:** 你的智能小助手
---
## 1. 问题描述
在笔记应用中,自动保存功能存在一个体验问题:即使用户正在积极地编辑文本(持续输入),计时器也不会被正确地重置或停止。这导致了在用户输入间隙,即使是非常短暂的停顿,也会触发不必要的、频繁的保存操作。
理想的行为是:**只有当用户停止输入一段时间后,自动保存才应该被触发。**
**相关文件:** `biji-qianduan/src/components/home/NoteEditor.vue`
## 2. 分析与诊断过程
### 2.1. 初步代码审查
我首先审查了 `NoteEditor.vue` 的源代码,重点关注以下几个方面:
* **Vditor 编辑器集成**: 代码通过 `new Vditor()` 正确初始化了编辑器。
* **事件监听**: 使用了 Vditor 的 `input` 事件回调来侦测内容变化。
* **防抖Debounce逻辑**: 在 `input` 回调中,存在一个看似正确的防抖实现:
* 使用 `let debounceTimer = null;` 在组件作用域内声明了一个计时器变量。
* 每次 `input` 事件触发时,都会先执行 `clearTimeout(debounceTimer);`
* 然后通过 `debounceTimer = setTimeout(...)` 设置一个新的 2 秒延迟的计时器来执行保存操作 `handleSave`
从表面上看,这段代码逻辑是健全的,它确实实现了防抖的核心思想。
### 2.2. 深入诊断:发现真正原因
既然代码逻辑本身没有问题,为什么还会出现用户描述的现象呢?我提出了一个新的假设:**问题并非出在用户输入时,而是出在切换笔记时。**
1. **`watch` 监听器**: 组件中使用 `watch` 来监听 `props.editData` 的变化。当用户从笔记列表选择一篇新笔记时,这个 `prop` 会更新。
2. **`setValue` 的副作用**: `watch` 回调函数会调用 `vditor.value.setValue(newData.content || '')` 来将新笔记的内容加载到编辑器中。
3. **意外的 `input` 事件**: 关键在于Vditor 的 `setValue` 方法在设置内容后,会**自动触发一次 `input` 事件**。
4. **问题触发流程**:
* 用户点击一篇新笔记。
* `watch` 监听到 `props.editData` 变化。
* `vditor.value.setValue()` 被调用,加载新内容。
* `setValue()` 触发了 `input` 事件。
* `input` 事件的回调被执行,启动了一个为期 2 秒的自动保存计时器。
* 即使用户立刻开始在这篇新笔记上输入(这会正确地重置计时器),那个由 `setValue` 启动的初始计时器依然可能在 2 秒后触发一次保存。
因此,**根本原因**是程序化地设置编辑器内容(`setValue`)意外地触发了为用户手动输入设计的自动保存逻辑。
## 3. 修复方案
为了解决这个问题,我们需要区分**用户手动输入**和**程序加载内容**这两种情况。只有前者才应该触发自动保存。
我采用了一个**标志位flag**的方案来解决此问题:
1. **引入标志位**: 在 `script setup` 中增加一个 `ref`