Skip to content

[TForm] nextTick中调用 clearValidate 方法,无法及时清除校验信息 #6639

Open

Description

@huchaomin

tdesign-vue-next 版本

1.19.2

重现链接

https://stackblitz.com/edit/dppu61az?file=package.json,src%2Fdemo.vue

重现步骤

Image 如上我写了4个nextTick,才清除了必填的校验

期望结果

1个nextTick就行

实际结果

No response

框架版本

No response

浏览器版本

No response

系统版本

No response

Node版本

No response

补充说明

No response

Activity

  1. github-actions commented on May 9, 2026

    @github-actions
    Contributor

    👋 @huchaomin,感谢给 TDesign 提出了 issue。
    请根据 issue 模版确保背景信息的完善,我们将调查并尽快回复你。

  2. guozi9999 commented on May 23, 2026

    @guozi9999
    Contributor

    https://stackblitz.c

    stackblitz 中的例子好像不能复现这个问题

  3. dongyikuan919 commented on May 23, 2026

    @dongyikuan919

    我看了下 TForm / TFormItem 这块,感觉这个问题像是 clearValidate() 和 FormItem 的自动校验 watcher 之间有时序竞争。

    当前 packages/components/form/form.tsx 里的 clearValidate 是同步遍历:

    children.value.forEach((child) => {
      if (isFunction(child.resetHandler) && needValidate(String(child.name), fields)) {
        child.resetHandler();
      }
    });

    但 packages/components/form/form-item.tsx 里同时有:

    watch(value, async () => {
      await validateHandler("change");
    }, { deep: true })

    所以如果业务代码在同一个 tick 里改了表单值,然后马上 nextTick(() => form.clearValidate()),可能出现:clearValidate -> resetHandler 已经清掉错误,但上一轮 value watcher / validateHandler 随后又把错误状态写回来。这个也能解释为什么示例里多写几个 nextTick 才能最终清掉。

    建议加一个回归测试:

    1. 先触发必填错误;
    2. 修改字段值;
    3. 一个 await nextTick() 后调用 clearValidate();
    4. 再 await nextTick(),断言 .t-is-error 和 .t-input__extra 都被清掉。

    实现上可以考虑两种方向:

    • 让 clearValidate 返回 Promise<void>,内部 reset 后 await nextTick(),确保对外时序稳定;
    • 或在 FormItem 内部加一个 reset/version 标记,clearValidate 后到来的旧 validateHandler 结果不再覆盖 TO_BE_VALIDATED 状态。

    第二种更稳,因为它能处理异步 validator 慢返回覆盖 reset 状态的问题。

  4. huchaomin commented on May 25, 2026

    @huchaomin
    Author

    https://stackblitz.c

    stackblitz 中的例子好像不能复现这个问题

    你注释掉一组 nextTick 就可以复现了

  5. dongyikuan919 commented on May 25, 2026

    @dongyikuan919

    明白了,注释掉一组 nextTick 后确实更容易把时序问题暴露出来。

    我理解这个问题的关键点不是单纯 “nextTick 里调用不生效”,而是 clearValidate 触发时表单项内部校验状态还没有完成同步,导致外层 tick 和字段状态更新 tick 存在先后差。建议后续可以把复现说明补成:保留/注释不同层级 nextTick 时的表现对比,这样维护者更容易判断是文档预期、调用时机问题,还是组件内部需要额外 flush。

  6. huchaomin commented on Jun 23, 2026

    @huchaomin
    Author

    这个问题还没进展么?

  7. dongyikuan919 commented on Jun 24, 2026

    @dongyikuan919

    目前看 issue 里还没有维护者的进一步反馈。

    我这边的理解还是更偏向 clearValidate 和 FormItem 内部 value watcher 触发的 change 校验之间存在时序竞争:clearValidate 已经把错误状态 reset 掉,但前一轮 validateHandler 的结果可能随后又把 error 状态写回来,所以才会表现成需要多层 nextTick 才能最终清掉。

    建议后续可以先补一个最小回归用例把这个时序固定下来:先触发 required 错误 -> 修改字段值 -> await nextTick() 后调用 clearValidate() -> 再 await nextTick() 断言错误态和提示都已清除。修复上单纯让 clearValidate 多等一个 tick 可能不够稳,更建议在 FormItem 内部加 reset/version 标记,避免 clearValidate 之后返回的旧校验结果覆盖 reset 后的状态。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    🐞 bugSomething isn't working

    Type

    No type

    Projects

    • Status
      No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions