readonly 是布尔属性,仅存在即生效,值被忽略;取消需 removeAttribute 或设 readOnly=false;date 类型会隐藏日历图标;React 中须用 readOnly={true};SSR 后需检查 hydration;只读纯前端防护,后端必须校验。

readonly 属性直接加在 <input> 或 <textarea> 标签里就生效,不用赋值、不写 "true" 或 "false"——写了反而多余甚至触发校验警告。
为什么 readonly="false" 不能取消只读
因为 readonly 是布尔属性,浏览器只看它“存不存在”,不解析它的值。只要写了这个属性名,无论后面跟什么字符串(readonly="false"、readonly="0"),都等价于只读状态。真正取消只读,必须用 removeAttribute('readonly') 或设 el.readOnly = false(但旧版 Safari 对后者响应不稳定)。
input[type="date"] 加 readonly 后下拉箭头消失怎么办
Chrome 和 Edge 下,readonly 会隐藏原生日期控件的触发图标,用户既不能编辑、也无法点开日历。这不是 bug,是浏览器对只读输入控件的统一处理逻辑。
- 如果需要保留日历图标 + 禁止编辑,得放弃
readonly,改用 CSS 隐藏原生控件 + 自定义展示 + JS 拦截所有修改路径(如oninput、onchange、onpaste) - 更轻量的折中方案:加
pointer-events: none到 input 上,并确保tabindex="-1"防止键盘聚焦,再用aria-readonly="true"声明语义 - 注意:仅靠
user-select: none或onfocus=this.blur()不可靠,前者不防粘贴,后者可能被 Tab 键绕过
React 里写 readonly 为什么没反应
React 使用驼峰命名规范,必须写成 readOnly={true}(小写 o,大写 O)。写成 readonly 会被忽略,控制台报 warning,且 DOM 中不会渲染该属性。
立即学习“前端免费学习笔记(深入)”;
- 动态控制时,别用字符串拼接:
<input readOnly={isLocked ? 'readonly' : ''}>❌ —— 应该用布尔值:<input readOnly={isLocked}>✅ - 服务端渲染(SSR)后,客户端 hydration 可能覆盖初始
readOnly状态,建议在useEffect中检查最终 DOM 是否真有readonly属性 - 如果字段要“大部分时间只读,权限变化后可编辑”,光切
readOnly不够,还得同步处理tabIndex、onFocus和键盘事件拦截,否则会出现“能聚焦却无法输入”的断裂体验
最易被忽略的一点:readonly 是纯前端防护,删掉属性、用控制台改 value、粘贴覆盖内容,浏览器照发——后端必须做二次校验,不能信任前端传来的只读字段值。



















