文章目录
最近一直在使用antdPro,发现ProFormDependency这个组件实现数据联动很好使用,于是记录一下:
ProFormDependency
详情:https://procomponents.ant.design/components/dependency
定义什么的可以看官网,下面直接上实例
(1)实现重复密码校验
1. bootstrap实现密码校验
在我很早以前写过这个,但是是使用的bootstrap,可以给你门看看代码
<form id="admin_form">
<div class="form-group">
<label for="exampleInputPassword1">当前密码</label>
<input type="password" class="form-control" name="password0" placeholder="请输入原始密码" autofocus>
</div>
<div class="form-group">
<label for="exampleInputPassword1">新的密码</label>
<input type="password" class="form-control" name="password1" placeholder="请输入新密码">
</div>
<div class="form-group">
<label for="exampleInputPassword1">确认密码</label>
<input type="password" class="form-control" name="password2" placeholder="请确认新密码">
</div>
<button type="submit" id="admin_btn" class="btn btn-success">保存</button>
</form>
<script>
//动态处理密码是否为空
$(function () {
$('form').bootstrapValidator({
message: 'This value is not valid',
feedbackIcons: {
valid: 'glyphicon glyphicon-ok',
invalid: 'glyphicon glyphicon-remove',
validating: 'glyphicon glyphicon-refresh'
},
fields: {
password0: {
validators: {
notEmpty: {
message: '密码不能为空'
}
}
},
password1: {
validators: {
identical: {
field: 'password2',
message: '两次输入的密码不相符'
}
}
},
password2: {
validators: {
identical: {
field: 'password1',
message: '两次输入的密码不相符'
}
}
}
}
});
});
</script>
<script>
$('#admin_btn').on('click', function (e) {
e.preventDefault()
var password0 = $('input[name="password0"]').val()
var password1 = $('input[name="password1"]').val()
var password2 = $('input[name="password2"]').val()
if(password0 == "" || password1==""){
window.alert('密码不能为空,请重新输入!')
window.location.replace(window.location.href)
return;
}
$.ajax({
url: '/admin',
type: 'post',
data: {
"password0": password0,
"password1": password1
},
dataType: 'json',
success: function (data) {
var err_code = data.err_code
if (err_code === 0) {
window.alert("密码修改成功,请重新登录!")
window.location.href = '/login'
} else if (err_code === 1) {
window.alert("原始密码输入错误,请重新输入!")
window.location.replace(window.location.href)
} else if (err_code === 500) {
window.alert('服务器忙,请稍后重试!')
}
}
})
return false;
})
</script>
当时是使用的bootstrapValidator去实现的前端校验,且用的是原生的form,提交密码用的是node。感觉代码量着实有点大。
2. antd ProComponents 实现密码
import ProForm, { ProFormDependency, ProFormText } from '@ant-design/pro-form';
import { Button, message } from 'antd';
import { HmacSHA256 } from 'crypto-js';
import Base64 from 'crypto-js/enc-base64';
import React, { FC } from 'react';
import FormFooter from 'src/components/form-footer';
import config from 'src/config';
import { useUpdatePassword } from 'src/services/account/hooks';
const formItemLayout = {
labelCol: { span: 3 },
wrapperCol: { span: 9 },
};
const PwdChange: FC = (): JSX.Element => {
const [{ loading }, requestUpdate] = useUpdatePassword();
//正则表达式 8-20字符,需包含大小写字母、数字和符号
const pattern = /^(?![A-z0-9]+$)(?=.[^%&',;=?$\x22])(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]).{8,20}$/;
return (
<>
<ProForm
{...formItemLayout}
layout="horizontal"
submitter={{
render: () => (
<FormFooter>
<Button type="primary" htmlType="submit" loading={loading}>
保存
</Button>
</FormFooter>
),
}}
onFinish={async values => {
const { OldPassword, NewPassword2 } = values;
try {
await requestUpdate({
data: {
//config.secretKey 是前端写死的一串密钥,下面是对密码的加密
OldPassword: Base64.stringify(HmacSHA256(OldPassword, config.secretKey)),
NewPassword: Base64.stringify(HmacSHA256(NewPassword2, config.secretKey)),
},
});
message.success('修改密码成功!');
} catch (e) {
message.error(e.message || '修改密码出错!');
}
}}
>
<ProFormText.Password
label="旧密码"
name="OldPassword"
placeholder="请输入旧密码"
rules={[{ required: true }]}
/>
<ProFormText.Password
name="NewPassword1"
label="新密码"
rules={[
{ required: true },
{ pattern, message: '8-20字符,需包含大小写字母、数字和符号' },
]}
placeholder="请输入新密码"
/>
//通过ProFormDependency 拿到密码1的值
<ProFormDependency name={['NewPassword1']}>
{({ NewPassword1 }) => (
<ProFormText.Password
label="确认密码"
name="NewPassword2"
placeholder="请再次输入新密吗"
rules={[
{ required: true },
{ pattern, message: '8-20字符,需包含大小写字母、数字和符号' },
{ //在这里使用antd 的validator通过promise去校验重复输入的密码和新密码是否一致
validator: (rule, value) =>
new Promise<void>((resolve, reject) => {
if (NewPassword1 === value) {
resolve();
} else {
reject(new Error('两次密码不一致,请检查'));
}
}),
},
]}
/>
)}
</ProFormDependency>
</ProForm>
<>
);
};
export default PwdChange;
2. 通过ProFormDependency控制表单项是否显示
<ProFormDependency name={['aaa']}>
{({ aaa }) =>
//判断aaa的值是否等于111,如果等于就显示该组件
aaa === '111' && (
<ProFormDateTimePicker
label="日期"
width="md"
name="date"
placeholder="选择日期"
rules={[{ required: true }]}
/>
)
}
</ProFormDependency>
(2)ProFormDependency 的name值
该name值支持一个数组,且还可以取到默认参数form
1. 为数组时
{renderList &&
map(renderList, (item, firstIndex) => (
<div key={item.PermID}>
<ProFormSwitch
label={item.Title}
name={['RoleLimit', firstIndex, 'Checked']}
initialValue
/>
<div style={{ display: 'none' }}>
<ProFormText
name={['RoleLimit', firstIndex, 'PermID']}
initialValue={item.PermID}
/>
</div>
<ProFormDependency name={['RoleLimit', firstIndex, 'Checked']}>
{depValues => {
//这个depValues就是个对象,里面包含了['RoleLimit', firstIndex, 'Checked'] 这三个属性的值
const { RoleLimit } = depValues;
return (
RoleLimit[firstIndex] &&
RoleLimit[firstIndex].Checked && (
<div style={{ marginLeft: 110 }}>
<RoleFormItem
key={firstIndex}
limitList={item.Children}
info="RoleLimit"
fatherIndex={firstIndex}
/>
</div>
)
);
}}
</ProFormDependency>
</div>
))}
2. name为二维数组时
<ProFormDependency name={[[info, fatherIndex, 'Children', sonIndex, 'Children']]}>
{(depValues, form) => {
console.log(depValues); //这里可以拿到name中[[]]数组里的值
const checkedGropus = get(
depValues,
[info, `${fatherIndex}`, 'Children', `${sonIndex}`, 'Children'],
[],
);
const defaultGroups = get(item, 'Children', []);
return (
<ProFormCheckbox
name={[info, fatherIndex, 'Children', sonIndex, 'All']}
colon={false}
initialValue={false}
fieldProps={{
onChange: e => {
const arr = e.target.checked ? filterCheckboxValue(defaultGroups) : [];
//可以在这里使用form的属性
form.setFields([
{
name: [info, fatherIndex, 'Children', sonIndex, 'Children'],
value: arr,
},
]);
},
indeterminate:
checkedGropus.length > 0 && checkedGropus.length < defaultGroups.length,
}}
>
<b>{item.Title}</b>
</ProFormCheckbox>
);
}}
</ProFormDependency>
<ProFormDependency name={[[info, fatherIndex, 'Children', sonIndex, 'All']]}>
{(depValues, form) => {
const defaultGroups = get(item, 'Children', []);
return (
item.Children && (
<div className={styles['limit-check']}>
<ProFormCheckbox.Group
layout="horizontal"
name={[info, fatherIndex, 'Children', sonIndex, 'Children']}
options={covertCheckBox(item.Children)}
initialValue={[]}
fieldProps={{
onChange: values => {
const checked = values.length === defaultGroups.length;
form.setFields([
{
name: [info, fatherIndex, 'Children', sonIndex, 'All'],
value: checked,
},
]);
},
}}
/>
</div>
)
);
}}
</ProFormDependency>