From cfb75c30cf020dd2b54a32e54341828ff002f60b Mon Sep 17 00:00:00 2001 From: Jerry Yan <792602257@qq.com> Date: Mon, 15 Jun 2026 11:13:25 +0800 Subject: [PATCH] WEb fix --- web/src/components/acp/AgentKindForm.vue | 148 +++++++---------------- 1 file changed, 42 insertions(+), 106 deletions(-) diff --git a/web/src/components/acp/AgentKindForm.vue b/web/src/components/acp/AgentKindForm.vue index c8fcae1..5211603 100644 --- a/web/src/components/acp/AgentKindForm.vue +++ b/web/src/components/acp/AgentKindForm.vue @@ -33,14 +33,28 @@ const emit = defineEmits<{ (e: 'cancel'): void }>() +// v-model 双向同步,但必须打破「W1 回填 → local 变 → W2 emit → 父 modelValue 变 → W1 再回填」 +// 的无限循环(曾导致表单任意输入/NSelect 选择即卡死浏览器)。 +// 关键:W2 emit 出去的就是 local 本身(同一引用),父组件直接持有该引用。当 W1 看到的 +// modelValue 与我们最近一次 emit 出去的值是同一个对象时,说明是回环而非真正的外部变更, +// 必须忽略;否则(如编辑模式下父组件 onMounted 用全新对象回填)才同步进 local。 const local = ref({ ...props.modelValue }) +let lastEmitted: typeof props.modelValue | undefined watch( () => props.modelValue, (v) => { + if (v === lastEmitted) return local.value = { ...v } }, ) -watch(local, (v) => emit('update:modelValue', v), { deep: true }) +watch( + local, + (v) => { + lastEmitted = v + emit('update:modelValue', v) + }, + { deep: true }, +) const argsText = computed({ get: () => local.value.args.join('\n'), @@ -52,7 +66,10 @@ const argsText = computed({ const allowlistText = computed({ get: () => (local.value.tool_allowlist ?? []).join('\n'), set: (v: string) => { - local.value.tool_allowlist = v.split('\n').map((x) => x.trim()).filter((x) => x !== '') + local.value.tool_allowlist = v + .split('\n') + .map((x) => x.trim()) + .filter((x) => x !== '') }, }) @@ -192,30 +209,15 @@ function removeMcpServer(idx: number) {