setvalidity 方法不存在,elementinternals 接口未定义该方法;实际可用的是 setformvalue、reportvalidity、checkvalidity 和只读的 validity 属性。

setValidity 方法到底能不能用?
setValidity 不是标准方法,它根本不存在于 ElementInternals 接口上。Chrome 从 92 版本起支持 ElementInternals,但只暴露了 setFormValue、setValidity 是常见误传——实际可用的是 setValidity 的“表兄弟”:setValidity 并未被任何浏览器实现,真正能用的是 setValidity?不,是 setValidity?错。正确方法是调用 setValidity?再确认一次:**没有 setValidity 方法**。
你查 MDN 或 TypeScript 类型定义会发现,ElementInternals 上只有:
setFormValue(提交值)setValidity(⚠️ 不存在)reportValidity(触发校验)checkValidity(只读检查)validity(只读属性,类型为 ValidityState)
setValidity?不行。靠 element.internals().setValidity?也不行。只能靠 element.internals().setFormValue 配合自定义 validity 模拟,或更实际的做法——用 element.internals().reportValidity() 触发原生逻辑,并在 willValidate 和 checkValidity 中手动控制返回值。
怎么让自定义元素参与表单验证?
核心不是“设状态”,而是“接管校验逻辑”。浏览器只认 checkValidity 返回 false 时认为无效,并据此设置 validity.valid 为 false。你无法直接写 internals.validity.valid = false(只读),但可以:
- 在自定义元素类中定义
checkValidity方法,返回false表示当前无效 - 在该方法里同步更新 UI(比如加
aria-invalid="true") - 确保
ElementInternals已通过this.attachInternals()获取并缓存 - 如果需要显示原生错误消息,必须配合
setFormValue+form关联 +reportValidity触发
class MyInput extends HTMLElement {
constructor() {
super();
this.internals = this.attachInternals();
}
checkValidity() {
const value = this.value || '';
const isValid = value.length >= 3;
// 手动同步 validity 状态(仅用于逻辑判断,不改变原生 UI)
this._isValid = isValid;
return isValid;
}
reportValidity() {
if (!this.checkValidity()) {
// 触发浏览器默认提示(仅当元素在 form 内且有 name 属性)
this.internals.setFormValue(null); // 清空值以确保校验生效
return false;
}
return true;
}
}
为什么 setFormValue(null) 有时能“触发”校验失败?
这不是 setFormValue 的本意,而是副作用。当调用 setFormValue(null) 且元素有 name 属性、处于 <form></form> 内时,浏览器会重新评估该控件是否满足必填(required)等约束。若此时 checkValidity() 返回 false,就会显示原生提示。
-
setFormValue(value)本身不校验,只设置提交值和关联状态 - 真正触发校验的是
reportValidity()或表单 submit 事件 - 如果你没重写
checkValidity,默认返回true,reportValidity就不会报错 -
setFormValue(undefined)和null效果相同,都表示“无值参与提交”
容易忽略的兼容性与调试点
- Chrome ≥ 92 支持
ElementInternals,Firefox 和 Safari **完全不支持**(截至 2024 年中);不要指望跨浏览器原生验证集成 -
internals.validity是只读对象,任何赋值(如internals.validity.valueMissing = true)静默失败 - 调试时用
console.log(this.internals.checkValidity())比看 DOM 属性更可靠 - 如果
reportValidity()没反应,先确认元素是否在<form></form>内、是否有name属性、是否已定义checkValidity
ElementInternals 的验证集成,改用纯 JS 校验 + 自定义错误提示——因为兼容性断层太深,而 setValidity 这个方法,压根就不存在。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











