0%

antd input能在DOM中看到密码问题

又是一个antd组件问题,密码组件在dom中可以看到密码,这算是一个低级的问题,为什么还会存在这种问题,翻看antd源代码,发现其实专门解决过这个问题,但是并没有解决彻底,在某些场景下仍然存在。

问题现象

F12在页面DOM中可以看到密码保存在value属性中,获得焦点时value会消失,但是又会自动出现。

问题定位

image.png

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

场景一:

image.png

如上页面,对话框使用了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', {
// initialValue:text.password,
rules: [
{ required: true, message: '请输入密码!' },
{
pattern: /\S+/,
message: '不允许出现空口令!',
},
{ validator: passwordValidator(form.getFieldValue('name') || '') },
],
})(
<Input
type={passwordType ? 'password' : 'text'}
// suffix={<Icon component={passwordType ? Close : Eye} onClick={this.changeType} />}
/>,
)}
</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'}
// suffix={<Icon component={passwordType ? Close : Eye} onClick={this.changeType} />}
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}/>;
}
}
-------------本文结束感谢您的阅读-------------