# 新建策略乐观更新功能实现
# 功能概述
在新建策略功能中实现了乐观更新(Optimistic Update)机制,提供更好的用户体验。当用户创建新策略时,界面会立即更新显示新策略,而不需要等待服务器响应。
# 实现原理
# 1. 乐观更新流程
- 用户提交表单 → 表单验证通过
- 立即更新UI → 触发
strategy-created事件,父组件立即添加新策略到列表 - 关闭弹窗 → 重置表单,关闭创建弹窗
- 异步保存 → 调用
createStrategyAPI 保存数据到服务器 - 结果处理:
- 成功:显示成功提示
- 失败:触发
strategy-rollback事件,回退UI状态
# 2. 回退机制
当API调用失败时,系统会自动:
- 从策略列表中移除失败的策略
- 如果当前选中的是失败的策略,则重置为默认策略
- 显示错误提示给用户
# 代码实现
# createStrategy.vue 组件
// 事件定义
const emit = defineEmits<{
'strategy-created': [strategy: any]
'strategy-rollback': [strategy: any]
}>()
// 确认创建策略
const confirmNewStrategy = async () => {
try {
await formRef.value.validate()
const newStrategyItem = {
name: newStrategy.value.name.trim(),
context: newStrategy.value.context.trim(),
objective: newStrategy.value.objective.trim(),
style: newStrategy.value.style.trim(),
tone: newStrategy.value.tone.trim(),
audience: newStrategy.value.audience.trim(),
response: newStrategy.value.response.trim()
}
// 乐观更新:先触发事件,让父组件立即更新UI
emit('strategy-created', newStrategyItem)
// 关闭弹窗并重置表单
show.value = false
resetStrategy()
try {
// 调用接口保存数据
const res = await createStrategy({
id: props.id,
extendData: newStrategyItem
})
if (res) {
console.log('策略创建成功:', res)
ElMessage.success('策略创建成功')
}
} catch (error) {
// 接口调用失败,触发回退事件
console.error('策略创建失败:', error)
emit('strategy-rollback', newStrategyItem)
// 显示错误提示
ElMessage.error('策略创建失败,请重试')
}
} catch (error) {
// 表单验证失败,不执行后续操作
console.log('表单验证失败:', error)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# optimize.vue 父组件
// 处理策略创建成功
const handleStrategyCreated = (newStrategy: any) => {
// 添加新策略到选项列表
strategyOptions.value.push(newStrategy)
// 设置为当前选中的策略
optimizeStrategy.value = newStrategy.name
}
// 处理策略创建失败回退
const handleStrategyRollback = (failedStrategy: any) => {
// 从选项列表中移除失败的策略
const index = strategyOptions.value.findIndex((item) => item.name === failedStrategy.name)
if (index !== -1) {
strategyOptions.value.splice(index, 1)
}
// 如果当前选中的是失败的策略,则重置为默认策略
if (optimizeStrategy.value === failedStrategy.name) {
optimizeStrategy.value = defaultStrategy.name
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 优势
- 更好的用户体验:用户无需等待服务器响应即可看到结果
- 响应速度快:界面立即更新,感觉更流畅
- 错误处理完善:失败时能够正确回退到之前的状态
- 用户反馈清晰:成功和失败都有相应的提示信息
# 注意事项
- 数据一致性:确保回退机制能够正确恢复之前的状态
- 错误处理:需要妥善处理网络错误、服务器错误等各种异常情况
- 用户体验:在失败时提供清晰的错误信息和重试选项