100 lines
3.3 KiB
Markdown
100 lines
3.3 KiB
Markdown
|
|
---
|
|||
|
|
name: 修复Table和Edit组件
|
|||
|
|
overview: 修复 Table.vue 的重复请求和搜索防抖问题,以及 Edit.vue 密码改为弹窗独立修改。
|
|||
|
|
todos:
|
|||
|
|
- id: fix-double-request
|
|||
|
|
content: "Table.vue: 添加 _skipFormWatch 标志,修复 mounted 和 watcher 导致的重复请求"
|
|||
|
|
status: completed
|
|||
|
|
- id: fix-keyword-search
|
|||
|
|
content: "Table.vue: 关键字搜索改为点击按钮/Enter触发,不再实时触发"
|
|||
|
|
status: completed
|
|||
|
|
- id: fix-password-dialog
|
|||
|
|
content: "Edit.vue: 密码字段改为弹窗独立修改,主表单提交排除密码数据"
|
|||
|
|
status: completed
|
|||
|
|
isProject: false
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 修复 Table 重复请求、搜索防抖、Edit 密码弹窗
|
|||
|
|
|
|||
|
|
## 1. 修复重复请求 - [Table.vue](d:\work\myst-web\src\components\Table.vue)
|
|||
|
|
|
|||
|
|
**根因**:`mounted()` 中既修改了 form 属性(触发 deep watcher),又显式调用了 `formDebounce`,两者可能各触发一次请求。
|
|||
|
|
|
|||
|
|
**方案**:在 data 中增加 `_skipFormWatch: true` 标志,mounted 中所有 form 初始化完成后调用一次 `formDebounce`,然后在 `$nextTick` 中将标志设为 false。watcher 中检查该标志,初始化期间跳过。
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// data 中
|
|||
|
|
_skipFormWatch: true,
|
|||
|
|
|
|||
|
|
// watcher 中
|
|||
|
|
form: {
|
|||
|
|
handler() {
|
|||
|
|
if (this._skipFormWatch) return;
|
|||
|
|
this.formDebounce(this);
|
|||
|
|
},
|
|||
|
|
deep: true
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// mounted 末尾
|
|||
|
|
this.formDebounce(this);
|
|||
|
|
this.$nextTick(() => { this._skipFormWatch = false; });
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 2. 搜索改为点击触发 - [Table.vue](d:\work\myst-web\src\components\Table.vue)
|
|||
|
|
|
|||
|
|
**方案**:将关键字搜索从实时触发改为点击搜索按钮触发。
|
|||
|
|
|
|||
|
|
- 新增 `searchKeyword: ""` data 属性,输入框 `v-model` 改为绑定 `searchKeyword`
|
|||
|
|
- 搜索按钮添加 `@click="doSearch"` 事件
|
|||
|
|
- `doSearch` 方法将 `searchKeyword` 赋值给 `form.keyword`(触发 watcher 进行搜索)
|
|||
|
|
- 输入框支持 Enter 键触发搜索(`@keyup.enter`)
|
|||
|
|
- 重置按钮也同步清空 `searchKeyword`
|
|||
|
|
|
|||
|
|
关键模板改动:
|
|||
|
|
|
|||
|
|
```html
|
|||
|
|
<el-input v-model="searchKeyword" @keyup.enter="doSearch" ...>
|
|||
|
|
<template #append>
|
|||
|
|
<el-button class="search-btn" @click="doSearch">
|
|||
|
|
<el-icon><Search/></el-icon>
|
|||
|
|
</el-button>
|
|||
|
|
</template>
|
|||
|
|
</el-input>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 3. 密码改为弹窗独立修改 - [Edit.vue](d:\work\myst-web\src\components\Edit.vue)
|
|||
|
|
|
|||
|
|
**方案**:
|
|||
|
|
|
|||
|
|
- 主表单中隐藏 password 类型字段,改为显示"修改密码"按钮
|
|||
|
|
- 新增密码修改弹窗(`el-dialog`),包含新密码 + 确认密码两个输入
|
|||
|
|
- 弹窗提交时校验两次输入一致,然后仅发送密码字段调用 `edit` API
|
|||
|
|
- 主表单 `onSubmit` 提交数据时过滤掉 password 类型字段
|
|||
|
|
|
|||
|
|
关键改动点:
|
|||
|
|
|
|||
|
|
**模板** - 密码字段区域(约第55行):
|
|||
|
|
|
|||
|
|
```html
|
|||
|
|
<!-- 原密码输入改为修改密码按钮 -->
|
|||
|
|
<el-button v-if="column.type=='password'" type="warning" @click="showPasswordDialog = true">
|
|||
|
|
修改密码
|
|||
|
|
</el-button>
|
|||
|
|
<!-- 其他非密码字段保持原样 -->
|
|||
|
|
<el-input v-model="form[column.value]" show-password v-else-if="..." />
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**data** 新增:
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
showPasswordDialog: false,
|
|||
|
|
passwordForm: { password: '', confirmPassword: '' },
|
|||
|
|
passwordColumn: null,
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**methods** 新增 `submitPassword` 和修改 `onSubmit`:
|
|||
|
|
|
|||
|
|
- `submitPassword`:校验密码一致性,调用 `edit` API 仅提交密码字段
|
|||
|
|
- `onSubmit`:提交时从 form 中排除 password 类型字段的数据
|
|||
|
|
|