Private
Public Access
1
0

新增:文档体系重构+CHANGELOG补充+发布产物清理

This commit is contained in:
2026-05-01 22:22:06 +08:00
parent 3e1a540b83
commit 6eaaa56eb6
164 changed files with 40346 additions and 64 deletions

View File

@@ -0,0 +1,33 @@
# 前端开发文档
本目录包含前端相关的分析和重构文档。
## 📊 文档列表
### 代码分析
- [layout-analysis.md](./layout-analysis.md) - 布局系统分析
- [components-analysis.md](./components-analysis.md) - 组件系统分析
- [frontend-refactor-summary.md](./frontend-refactor-summary.md) - 前端重构总结
## 🎯 前端技术栈
### 核心框架
- **Vue 3** - 渐进式 JavaScript 框架
- **Vite** - 下一代前端构建工具
- **Arco Design Vue** - 企业级 UI 组件库
### 状态管理
- Pinia - Vue 官方状态管理库
- Composables - 组合式 API 复用
### 主要组件
- FileSystem - 文件管理
- DatabaseClient - 数据库客户端
- Settings - 设置面板
- UpdateNotification - 更新通知
## 💡 相关文档
- [架构设计/](../架构设计/) - 整体架构设计
- [模块文档/](../模块文档/) - 各模块实现文档
- [04-功能迭代/GO-DESK-2.数据库客户端/设计文档/架构设计/前端架构设计.md](../04-功能迭代/GO-DESK-2.数据库客户端/设计文档/架构设计/前端架构设计.md) - 数据库客户端前端架构

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

View File

@@ -0,0 +1,202 @@
# 前端代码重构总结
## 📋 重构目标
提高可维护性和可读性,通过调整代码结构、命名和组织,而不是机械地拆分方法。
## ✅ 完成的工作
### 1. 创建统一的 API 层
**目录结构:**
```
frontend/src/api/
├── index.ts # 统一导出
├── types.ts # 类型定义(精简命名)
├── connection.ts # 连接管理 API
├── database.ts # 数据库和表 API
├── structure.ts # 表结构 API
├── query.ts # SQL 查询 API
├── tab.ts # 标签页 API
└── system.ts # 系统信息 API
```
**改进点:**
- ✅ 消除了重复的 `window.go?.main?.App?.XXX` 检查
- ✅ 统一的错误处理
- ✅ 类型安全的 API 调用
- ✅ 简化类型命名(`DbConnection``Connection`
**重构的文件(使用新 API 层):**
- ConnectionTree.vue
- db-cli/index.vue
- useTabPersistence.js
- useStructureStore.ts
- DeviceTest.vue
### 2. 拆分 ResultPanel.vue 组件
**原始问题:**
- 2437 行代码
- 职责混乱(结果展示、分页、消息日志、表结构、历史记录)
**新的组件结构:**
```
frontend/src/views/db-cli/components/result/
├── ResultTab.vue # 结果标签页容器
├── ResultStats.vue # 统计信息栏
├── ResultTable.vue # 表格视图(含分页)
├── ResultJson.vue # JSON 视图
├── MessageLog.vue # 消息日志
├── types.ts # 类型定义
├── index.ts # 导出
└── README.md # 组件文档
```
**组件职责划分:**
- **ResultTab**: 组合子组件,管理视图切换
- **ResultStats**: 显示行数、执行时间、视图切换按钮
- **ResultTable**: 表格展示、分页、高度自适应
- **ResultJson**: JSON 格式展示和语法高亮
- **MessageLog**: 消息列表展示
### 3. 创建通用 Composables
**目录结构:**
```
frontend/src/composables/
├── index.ts # 导出
├── useLocalStorage.ts # localStorage 操作
├── useDebounce.ts # 防抖函数
├── useTablePage.ts # 表格分页
└── useApiError.ts # API 错误处理
```
**功能说明:**
#### useLocalStorage
```typescript
const [value, setValue, clearValue] = useLocalStorage('key', defaultValue)
```
- 自动同步到 localStorage
- 支持深度监听
- 错误处理
#### useDebounce
```typescript
const debouncedValue = useDebounce(sourceValue, 300)
const debouncedFn = debounceFn(callback, 300)
```
- 值防抖
- 函数防抖
#### useTablePage
```typescript
const {
currentPage,
canGoPrev,
canGoNext,
nextPage,
prevPage,
reset
} = useTablePage({ pageSize: 10 })
```
- 分页状态管理
- 前后翻页控制
- 页码跳转
#### useApiError
```typescript
const { error, showError, clearError } = useApiError()
showError(err, '操作失败')
```
- 统一错误处理
- 自动显示错误消息
- 错误状态管理
### 4. 配置改进
**vite.config.js**
- 添加 `@` 路径别名 → `src`
- 提高导入路径可读性
## 📊 重构效果
### 代码质量提升
-**消除重复代码**: 9 个文件中的重复 API 调用检查
-**职责分离**: ResultPanel 从 2437 行拆分为 5 个小组件
-**类型安全**: 统一的 TypeScript 类型定义
-**命名精简**: 类型名称更简洁易读
### 可维护性提升
-**集中管理**: 所有后端 API 在 `/api` 目录
-**组件复用**: 通用 composables 可在多个组件使用
-**清晰结构**: 每个组件/文件职责单一明确
### 可读性提升
-**简洁导入**: `import { xxx } from '@/api'` 代替长路径
-**语义化命名**: 组件和函数名清晰表达用途
-**文档完善**: 组件 README 说明使用方法
## 🔄 后续优化建议
### 短期(立即可做)
1. 在 ResultPanel.vue 中引入并测试新的 ResultTab 组件
2. 用 useLocalStorage 替换组件中的直接 localStorage 操作
3. 用 useApiError 统一错误处理
### 中期(逐步迁移)
1. 将表结构功能从 ResultPanel 拆分为 StructureTab 组件
2. 将查询历史拆分为 QueryHistory 组件
3. 简化 ResultPanel 为纯标签页容器
### 长期(架构优化)
1. 考虑使用 Pinia 进行状态管理
2. 实现路由系统(替代 tab 切换)
3. 添加单元测试
## 📝 代码示例
### 之前 vs 之后
**之前(每个组件都要检查 API**
```typescript
if (!window.go?.main?.App?.GetDatabases) {
throw new Error('Go 后端未就绪')
}
const databases = await window.go.main.App.GetDatabases(id)
```
**之后(统一 API 层):**
```typescript
import { getDatabases } from '@/api'
const databases = await getDatabases(id)
```
**之前(直接使用 localStorage**
```typescript
const saved = localStorage.getItem('key')
const value = saved ? JSON.parse(saved) : defaultValue
localStorage.setItem('key', JSON.stringify(value))
```
**之后(使用 composable**
```typescript
const [value, setValue] = useLocalStorage('key', defaultValue)
```
## ✅ 构建测试
- ✅ 所有修改通过构建测试
- ✅ 应用运行正常
- ✅ 数据查询功能正常
## 🎯 总结
本次重构遵循以下原则:
-**提高可维护性**: 集中管理、职责分离、消除重复
-**提高易读性**: 精简命名、清晰结构、完善文档
-**合理拆分**: 按职责拆分组件,不机械地拆分方法
-**保持功能**: 所有功能正常工作,无破坏性修改
重构后的代码更易于理解、维护和扩展!

View File

@@ -0,0 +1,11 @@
# 代码分割优化
本目录包含前端代码分割优化相关文档。
## 📄 文档列表
- [code-splitting-optimization.md](./code-splitting-optimization.md) - 代码分割优化方案
## 🎯 优化目标
通过代码分割减少初始加载时间,提升应用性能。

View File

@@ -0,0 +1,179 @@
# 代码分割优化报告
## 优化目标
通过动态 import() 减小初始包大小,提升首屏加载速度。
## 优化方案
将 CodeEditor 组件改为异步加载defineAsyncComponent
## 优化结果
### 📊 包大小对比
| 文件 | 优化前 | 优化后 | 变化 |
|------|--------|--------|------|
| **index.js** | 2,955 KB<br>(gzip: 907 KB) | 2,575 KB<br>(gzip: 778 KB) | **-380 KB**<br>**(-129 KB gz)** |
| **CodeEditor.js** (新增) | - | 381 KB<br>(gzip: 129 KB) | +381 KB |
| **codemirror.js** (独立) | 包含在 index.js | 606 KB<br>(gzip: 218 KB) | 独立 chunk |
### 🎯 优化效果
-**主包减少 13%**2.95 MB → 2.57 MB
-**Gzip 减少 14%**907 KB → 778 KB
-**按需加载**CodeMirror 仅在打开编辑器时加载
-**首屏更快**:减少 380 KB 初始下载
### 📦 代码分割详情
**优化前**
```
index.js (2,955 KB)
├── CodeMirror (605 KB) ← 在主包中
└── CodeEditor (381 KB) ← 在主包中
```
**优化后**
```
index.js (2,575 KB) ← 主包,启动时加载
CodeEditor.js (381 KB) ← 按需加载,打开编辑器时
codemirror.js (606 KB) ← 按需加载,打开编辑器时
```
## 实施细节
### 修改的文件
**`frontend/src/components/FileSystem/components/FileEditorPanel.vue`**
### 修改内容
#### 1. 添加异步组件定义
```typescript
import { defineAsyncComponent } from 'vue'
// 异步加载 CodeEditor 组件,减少初始包大小
const AsyncCodeEditor = defineAsyncComponent({
loader: () => import('@/components/CodeEditor.vue'),
delay: 200, // 200ms 后显示加载状态
timeout: 10000 // 10 秒超时
})
```
#### 2. 替换组件使用
```vue
<!-- 原来 -->
<CodeEditor ... />
<!-- 现在 -->
<AsyncCodeEditor ... />
```
### 加载体验
- **首次打开编辑器**:延迟 ~200ms可接受
- **后续打开**:无延迟(已缓存)
- **首屏加载**:快 ~380 KB
## 性能分析
### 首屏加载速度提升
**假设 3G 网络1 Mbps**
- 优化前2.95 MB → ~7.3 秒
- 优化后2.57 MB → ~6.4 秒
- **提升****~0.9 秒**
**假设 WiFi10 Mbps**
- 优化前2.95 MB → ~0.73 秒
- 优化后2.57 MB → ~0.64 秒
- **提升****~0.09 秒**
### Gzip 压缩效果更明显
- **减少 129 KB**Gzip 后)
- **相当于减少 14% 初始下载**
## 改动评估
| 项目 | 评估 |
|------|------|
| **修改文件数** | 1 个 |
| **代码修改量** | ~10 行 |
| **改动复杂度** | ⭐ 简单 |
| **风险评估** | 🟢 低 |
| **收益** | 🟢 高 |
| **用户体验** | ✅ 无明显影响 |
## 后续优化建议
### 可选优化(优先级低)
1. **异步加载 Markdown 预览**~400 KB
- 收益:额外减少 400 KB
- 改动中等4-5 个文件)
- 风险Markdown 渲染可能延迟
2. **异步加载 Mermaid 图表**~1.5 MB
- 收益:图表按需加载
- 改动:较大(需要改造 markedExtensions
- 风险:图表显示可能延迟
3. **CodeMirror 语言包按需加载**~600 KB → ~100 KB
- 收益:减少 500 KB
- 改动:大(需要改造语言包加载逻辑)
- 风险:高
### 当前状态
**已完成**CodeEditor 异步加载
**效果**:主包减少 380 KB (13%)
**用户体验**:无明显负面影响
## 技术细节
### defineAsyncComponent 参数
```typescript
{
loader: () => import('./Component.vue'), // 动态导入
delay: 200, // 延迟显示 loadingms
timeout: 10000, // 加载超时ms
suspensible: false // 是否与 Suspense 集成
}
```
### 加载流程
1. 用户打开文件
2. Vue 检测到 AsyncCodeEditor
3. 触发动态 import()
4. CodeEditor chunk (381 KB) 开始加载
5. CodeMirror chunk (606 KB) 开始加载
6. 200ms 后(如有延迟)显示加载状态
7. 加载完成,渲染编辑器
### 浏览器缓存
- **首次访问**:下载 index.js (2.57 MB)
- **打开编辑器**:下载 CodeEditor.js + codemirror.js
- **后续访问**:从缓存加载,无额外下载
## 总结
通过仅修改 **1 个文件**,增加 **~10 行代码**,成功将初始包大小减少了 **13%**380 KBGzip 后减少 **14%**129 KB
**用户收益**
- ✅ 首屏加载更快
- ✅ 初始下载更少
- ✅ 编辑器体验无明显影响
**开发收益**
- ✅ 改动小,风险低
- ✅ 无需重构现有代码
- ✅ 易于维护
---
**实施日期**2026-02-04
**优化类型**代码分割Code Splitting
**状态**:✅ 完成
**验证**:✅ 构建成功,功能正常

View File

@@ -0,0 +1,13 @@
# 布局分析
本目录包含前端布局分析相关文档。
## 📄 文档列表
- [layout-analysis.md](./layout-analysis.md) - 布局分析报告
## 🎯 分析内容
- 布局结构分析
- 响应式设计评估
- 布局优化建议

View File

@@ -0,0 +1,168 @@
# Go Desk 表格高度问题分析
## 📐 整体布局结构
### 完整布局层级树
```
App.vue (100vh)
└── a-layout (db-cli-layout, height: 100vh)
├── a-layout-sider (sidebar, width: 280px, fixed)
│ └── ConnectionTree
└── a-layout (main-layout, flex: 1)
├── a-layout-content (editor-area, 动态高度百分比)
│ └── SqlEditor
├── div (editor-result-divider, 4px)
└── a-layout-content (result-area, flex: 1) ← 关键:应占据剩余空间
└── ResultPanel (result-panel-wrapper, height: 100%)
└── a-tabs (result-tabs, height: 100%)
└── a-tab-pane (result-content, flex: 1, padding: 12px)
└── result-data-wrapper (flex: 1)
├── result-stats (固定高度, margin-bottom: 4px)
└── result-table-container (flex: 1, overflow: hidden)
├── a-table (scroll.y = tableScrollHeight)
└── custom-pagination (固定高度)
```
## 🔍 问题诊断
### 当前症状
1. **底部有空白** - 表格下方有大量未使用的空白区域
2. **表格没有填满可用空间**
### 布局断点分析
#### 断点1: main-layout
-`flex: 1` - 正确,应占据除 sidebar 外的所有空间
-`flex-direction: column`
#### 断点2: result-area
-`flex: 1` - 正确
- ✅ 应该占据 main-layout 中除 editor-area 外的所有空间
#### 断点3: result-content
- ⚠️ `flex: 1` + `padding: 12px`
- ✅ padding 会占用空间,但 flex: 1 应该让内容区填满剩余空间
#### 断点4: result-data-wrapper
-`flex: 1` - 正确
#### 断点5: result-table-container (问题所在)
-`flex: 1`
- ❌ 内部使用 `scroll.y` 固定高度,与 flex 冲突
### 核心问题
**Arco Table 的 `scroll.y` 属性的工作机制**
```javascript
// 当设置 scroll.y = 400 时
<a-table :scroll="{ y: 400 }">
// Arco Table 内部结构:
.arco-table {
height: auto; // 或固定高度
}
.arco-table-body {
max-height: 400px; // 这是滚动高度
overflow: auto;
}
```
**问题**
- `scroll.y` 设置的是 **tbody 的滚动高度**(不包括表头)
- 表格总高度 = 表头高度 + scroll.y
-`scroll.y` 过小时,表格下方会有空白
-`scroll.y` 过大时,表格会超出容器
### 当前计算逻辑
```javascript
// 当前计算公式
const scrollY = containerHeight - paginationHeight - 12;
// 问题:
// 1. containerHeight = result-table-container 的 offsetHeight
// 2. 但 result-table-container 是 flex: 1它的实际高度由父容器决定
// 3. 如果 scroll.y 小于实际可用空间,就会有空白
```
## 🎯 正确的解决方案
### 方案对比
#### ❌ 错误方案:直接计算 scroll.y
```javascript
// 问题:计算的值可能不准确
const scrollY = containerHeight - paginationHeight - 12;
```
#### ✅ 正确方案:使用 CSS 让表格自动填充
**移除 scroll.y纯 CSS 控制**
```vue
<a-table
:columns="tableColumns"
:data="pagedData"
:pagination="false"
class="result-table"
/>
```
```css
.result-table-container {
flex: 1;
min-height: 0;
display: flex;
flex-direction: column;
}
.result-table-container :deep(.arco-table) {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
}
.result-table-container :deep(.arco-table-body) {
flex: 1;
overflow-y: auto;
overflow-x: auto;
}
```
### Arco Table 的 DOM 结构
```
.arco-table
├── .arco-table-header (表头,固定高度)
└── .arco-table-body (表体flex: 1, overflow: auto)
```
**关键**
- 表头自动高度(由内容决定)
- 表体填充剩余空间
- overflow 在表体上,不是整个表格
## 📋 行动计划
### 步骤1: 移除 scroll.y 属性
### 步骤2: 使用纯 CSS flex 布局
### <20>骤骤3: 确保每个容器有正确的 flex 设置
### 步骤4: 测试不同数据量下的表现
## 🎨 期望效果
- ✅ 表格填满所有可用空间(无底部空白)
- ✅ 数据少时:表头 + 空行 + 分页控件填满空间
- ✅ 数据多时:表头 + 可滚动表体 + 分页控件
- ✅ 窗口调整时自动响应
## 🔧 待确认
1. 当前浏览器控制台输出的具体数值是多少?
2. 数据量是多还是少?(行数大概多少)
3. 空白区域大概有多少像素?

View File

@@ -0,0 +1,13 @@
# 组件分析
本目录包含前端组件分析相关文档。
## 📄 文档列表
- [components-analysis.md](./components-analysis.md) - 组件分析报告
## 🎯 分析内容
- 组件结构分析
- 组件依赖关系
- 组件优化建议

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,315 @@
# 为什么编译器没发现初始化顺序问题
**日期**: 2026-01-31
**问题**: 第5次 `Cannot access before initialization` 错误
**根本原因**: 函数定义位置导致的初始化顺序问题
---
## 🐛 问题描述
### 错误信息
```
ReferenceError: Cannot access 'Vn' before initialization
```
### 问题代码(修复前)
```typescript
// Line 362: 在 fileEditorPanelConfig computed 中使用
canPreviewFile: isEditableWithPreview(currentFileName),
// Line 869: 函数定义在很远的地方
const isEditableWithPreview = (filename: string): boolean => {
const ext = filename.split('.').pop()?.toLowerCase() || ''
return ['html', 'htm', 'md', 'markdown'].includes(ext)
}
```
**问题**:函数在**第362行被使用**,但在**第869行才定义**
---
## ❓ 为什么 TypeScript 没发现?
### 原因1JavaScript 的函数提升
```javascript
// 这是合法的 JavaScript/TypeScript
sayHello() // ✅ 可以调用
function sayHello() {
console.log('Hello!')
}
```
**原因**:函数声明(`function sayHello()`会被提升到作用域顶部TypeScript 编译器认为这是合法的。
### 原因2箭头函数的提升规则
```javascript
// 这也是合法的
const sayHello = () => console.log('Hello!')
```
虽然箭头函数不会被提升但在同一个作用域内TypeScript 认为在执行时函数已经存在。
### 原因3Vue 3 Setup 函数的特殊性
```vue
<script setup lang="ts">
// Vue 的 <script setup> 会被编译成一个大的 setup() 函数
// 所有顶层声明都在同一个函数作用域内
const config = computed(() => {
return useHelper() // TypeScript 认为这是合法的
})
const useHelper = () => { ... } // 函数在后面定义
</script>
```
**关键问题**
- TypeScript 只检查**语法和类型**,不检查**运行时执行顺序**
- Vue 的 `computed` 在定义时会**立即执行 getter 函数**以收集依赖
- 如果 getter 内部引用了尚未初始化的值,就会报错
---
## 🔍 如何让编译器发现这类问题?
### 方法1使用 ESLint 规则(推荐)⭐⭐⭐⭐⭐
**安装 ESLint 插件:**
```bash
npm install -D eslint-plugin-vue
```
**配置 `.eslintrc.js`**
```javascript
module.exports = {
rules: {
// 检测变量使用前定义
'no-use-before-define': ['error', {
functions: false, // 允许函数提升
classes: true, // 类必须先定义
variables: true // 变量必须先定义
}],
// Vue 特定规则
'vue/no-setup-props-destructure': 'error',
'vue/no-ref-as-operand': 'error'
}
}
```
### 方法2启用严格的 TypeScript 配置⭐⭐⭐⭐
**`tsconfig.json`**
```json
{
"compilerOptions": {
"strict": true,
// 检测可能的 null/undefined
"noImplicitAny": true,
// 不允许隐式 any
"strictInitializationChecks": true
}
}
```
### 方法3使用 Prettier 格式化 + 自定义规则⭐⭐⭐
创建 `.prettierrc.js`
```javascript
module.exports = {
// 强制一致的代码顺序
plugins: ['@trivago/prettier-plugin-sort-imports'],
importOrder: [
'^vue$', // Vue 相关
'^@/(.*)$', // 项目导入
'^[./]' // 相对导入
]
}
```
### 方法4自定义 ESLint 规则检测函数定义顺序⭐⭐⭐⭐⭐
创建 `.eslintrc.js` 自定义规则:
```javascript
module.exports = {
plugins: [
['local-rules', {
rules: {
'require-functions-before-computed': {
meta: {
type: 'suggestion',
docs: {
description: '要求函数定义在 computed 属性之前'
}
},
create: (context) => ({
CallExpression(node) {
// 检测 computed 调用中的函数引用
if (node.callee.name === 'computed') {
// 检查是否引用了后面定义的函数
// ... 实现逻辑
}
}
})
}
}
}]
]
}
```
### 方法5使用 unbuild/rollup 插件检测⭐⭐⭐
```javascript
// vite.config.ts
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [
{
name: 'detect-initialization-order',
transform(code, id) {
if (id.endsWith('.vue')) {
// 分析代码,检测 computed 中的函数引用
// 检查这些函数是否在 computed 之前定义
}
}
}
]
})
```
---
## ✅ 最佳实践
### 1. 代码组织顺序(强烈推荐)
```vue
<script setup lang="ts">
// 1. 导入
import { ref, computed } from 'vue'
import { useFileOperations } from './composables/useFileOperations'
// 2. 工具函数(最先定义)
const isEditableWithPreview = (filename: string): boolean => {
return ['html', 'htm', 'md', 'markdown'].includes(ext)
}
const validateFileName = (name: string): boolean => {
return !illegalChars.test(name)
}
// 3. 状态变量ref
const fileList = ref<FileItem[]>([])
const fileLoading = ref(false)
// 4. Composables 解构
const { listDirectory, readFile } = useFileOperations({...})
const { filePath, navigate } = usePathNavigation({...})
// 5. Computed 属性(最后)
const toolbarConfig = computed(() => ({
canPreviewFile: isEditableWithPreview(currentFileName) // ✅ 函数已定义
}))
// 6. 事件处理函数
const handleSave = () => { ... }
// 7. 生命周期钩子
onMounted(() => { ... })
</script>
```
### 2. 添加注释分区
```typescript
// ========== 导入 ==========
import ...
// ========== 类型定义 ==========
interface ...
// ========== 工具函数 ==========
const helper1 = () => { ... }
const helper2 = () => { ... }
// ========== 状态变量 ==========
const state1 = ref(...)
const state2 = ref(...)
// ========== Composables ==========
const { ... } = useComposable1()
const { ... } = useComposable2()
// ========== 计算属性 ==========
const computed1 = computed(() => { ... })
const computed2 = computed(() => { ... })
// ========== 事件处理 ==========
const handleEvent1 = () => { ... }
// ========== 生命周期 ==========
onMounted(() => { ... })
```
### 3. 使用 TypeScript 的 `declare` 预声明(临时方案)
```typescript
// 在文件顶部预先声明
declare function isEditableWithPreview(filename: string): boolean
// 然后在后面定义
const isEditableWithPreview = (filename: string): boolean => {
// ...
}
```
**但这不是好的解决方案,只是让编译器闭嘴。**
---
## 📊 错误检测能力对比
| 方法 | 能否检测此问题 | 误报率 | 配置难度 | 推荐度 |
|------|---------------|--------|----------|--------|
| TypeScript | ❌ | 低 | 低 | ⭐⭐⭐ |
| ESLint no-use-before-define | ❌ | 中 | 低 | ⭐⭐⭐ |
| ESLint 自定义规则 | ✅ | 低 | 高 | ⭐⭐⭐⭐ |
| 代码组织规范 | ✅ | 无 | 低 | ⭐⭐⭐⭐⭐ |
| Vite 插件 | ✅ | 低 | 中 | ⭐⭐⭐⭐ |
| 人工 Code Review | ✅ | 低 | 高 | ⭐⭐⭐ |
---
## 🎯 总结
### 为什么编译器没发现:
1. **JavaScript 的函数提升机制**
2. **TypeScript 只检查类型,不检查运行时执行顺序**
3. **Vue 3 的 setup 函数在同一作用域内**
### 如何预防:
1.**遵循固定的代码组织顺序**(最有效)
2.**使用 ESLint 自定义规则**
3.**编写单元测试检测初始化错误**
4.**使用 TypeScript 的严格模式**
5.**Code Review 时检查函数定义位置**
### 本次修复:
-`isEditableWithPreview` 函数从第869行移到第295行
- 现在它在所有 computed 属性**之前**定义
- 编译成功 ✅
---
**生成时间**: 2026-01-31
**编译状态**: ✅ 成功 (30.285s)
**下次预防**: 遵循代码组织最佳实践

View File

@@ -0,0 +1,18 @@
- [x] 260430-1
底部的分页 让它完全靠在底部,不管有多是个文件和文件夹, 看下图
![x](clipboard_20260430_093933.png)
- [x] 260430-2:
当前文档中 中加载图片渲染失败,
![图片加载失败](clipboard_20260430_095715.png)
- [x] 260430-3:
更换一下 vue 这个文件类型的图标
E:/wk-lab/u-desk/docs/06-前端开发/clipboard_20260430_101128.png
- [x] 260430-4:
优化将,本地/远程连接融合到 导航组件的最前面,视觉效果上做融合,讨论下方案
![图片加载失败](clipboard_20260430_103035.png)
- [ ] 260430-5:
打开的时候自动预览上次打开的文件和位置