又是一个antd组件问题,密码组件在dom中可以看到密码,这算是一个低级的问题,为什么还会存在这种问题,翻看antd源代码,发现其实专门解决过这个问题,但是并没有解决彻底,在某些场景下仍然存在。
问题现象
F12在页面DOM中可以看到密码保存在value属性中,获得焦点时value会消失,但是又会自动出现。
问题定位

通过在input元素上打断点调试,发现antd input组件曾经解决过此问题,见https://github.com/ant-design/ant-design/issues/20541,但是其解决方法是在componentDidMount,onFocus,onBlur,onChange四个时机删除value属性,这就是为什么获得焦点时value会消失,但是为什么又会自动出现呢,因为有一些场景这种解法是无效的。
场景一:

如上页面,对话框使用了dva上的状态,背后的列表页面5s定时刷新导致dva上状态变化,导致对话框update,这时value又会出现。
场景二:
包裹在Form.Item(V4)或getFieldDecorator(V4之前)里面的Input不是第一层节点,此时Input失去焦点时,value也会又出现。
例1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <FormItem labelCol={{ span: 6 }} wrapperCol={{ span: 14 }} label="新密码"> <PasswordTooltip name={form.getFieldValue('name')} password={form.getFieldValue('password')} > {form.getFieldDecorator('password', { rules: [ { required: true, message: '请输入密码!' }, { pattern: /\S+/, message: '不允许出现空口令!', }, { validator: passwordValidator(form.getFieldValue('name') || '') }, ], })( <Input type={passwordType ? 'password' : 'text'} />, )} </PasswordTooltip> </FormItem>
|
例2:
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
| <FormItem shouldUpdate> {() => ( <FormItem labelCol={{ span: 6 }} wrapperCol={{ span: 14 }} label="新密码" name='newPassword' rules={[ { required: switchState, message: '请输入新密码' }, { pattern: /\S+/, message: '不允许出现空口令', }, this.validatePassword, this.validateToOldPassword, this.validateToConfirm, this.validateCloudname, ]} > <PasswordTooltip name={this.formRef.current && this.formRef.current.getFieldValue('username')} password={this.formRef.current && this.formRef.current.getFieldValue('newPassword')} > <Input disabled={!switchState} type={passwordType ? 'password' : 'text'} onChange={(e) => { this.formRef.current.setFieldsValue({ 'newPassword': e.target.value }); this.formRef.current.validateFields(['newPassword']); }} /> </PasswordTooltip> </FormItem>
)} </FormItem>
|
场景三:
包裹在Form.Item(V4)或getFieldDecorator(V4之前)里面的Input,onchange的触发会失效,这样输入一个字符后,value又会出现。
解决方案
将Input包装了一层,在其componentDidUpdate中删除value属性。不解为什么antd input不在componentDidUpdate中删除value属性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import React, { PureComponent } from 'react'; import { Input } from 'antd';
export default class ClearValueInput extends PureComponent {
componentDidUpdate() { if (this.input && this.input.input) { if (this.input.input.hasAttribute('value')) { setTimeout(() => this.input.input.removeAttribute('value')); } } } saveInput = (input) => { this.input = input; }
render() { return <Input {...this.props} ref={this.saveInput}/>; } }
|