perf(ContactEdit): using Form (#8015)

This commit is contained in:
neverland 2021-01-26 21:10:54 +08:00 committed by GitHub
parent 4f1521010a
commit 8c7a265082
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 49 additions and 97 deletions

View File

@ -6,6 +6,7 @@ import { isMobile } from '../utils/validate/mobile';
// Components // Components
import Cell from '../cell'; import Cell from '../cell';
import Form from '../form';
import Field from '../field'; import Field from '../field';
import Button from '../button'; import Button from '../button';
import Dialog from '../dialog'; import Dialog from '../dialog';
@ -38,42 +39,14 @@ export default createComponent({
emits: ['save', 'delete', 'change-default'], emits: ['save', 'delete', 'change-default'],
setup(props, { emit }) { setup(props, { emit }) {
const state = reactive({ const contact = reactive({
contact: {
...DEFAULT_CONTACT, ...DEFAULT_CONTACT,
...props.contactInfo, ...props.contactInfo,
},
errorInfo: {
name: '',
tel: '',
},
}); });
const onFocus = (key) => {
state.errorInfo[key] = '';
};
const getErrorMessageByKey = (key) => {
const value = state.contact[key].trim();
switch (key) {
case 'name':
return value ? '' : t('nameInvalid');
case 'tel':
return props.telValidator(value) ? '' : t('telInvalid');
}
};
const onSave = () => { const onSave = () => {
const isValid = ['name', 'tel'].every((item) => { if (!props.isSaving) {
const msg = getErrorMessageByKey(item); emit('save', contact);
if (msg) {
state.errorInfo[item] = msg;
}
return !msg;
});
if (isValid && !props.isSaving) {
emit('save', state.contact);
} }
}; };
@ -81,7 +54,7 @@ export default createComponent({
Dialog.confirm({ Dialog.confirm({
title: t('confirmDelete'), title: t('confirmDelete'),
}).then(() => { }).then(() => {
emit('delete', state.contact); emit('delete', contact);
}); });
}; };
@ -93,7 +66,7 @@ export default createComponent({
type="danger" type="danger"
text={t('save')} text={t('save')}
loading={props.isSaving} loading={props.isSaving}
onClick={onSave} nativeType="submit"
/> />
{props.isEdit && ( {props.isEdit && (
<Button <Button
@ -109,7 +82,7 @@ export default createComponent({
const renderSwitch = () => ( const renderSwitch = () => (
<Switch <Switch
vModel={state.contact.isDefault} v-model={contact.isDefault}
size={24} size={24}
onChange={(event) => { onChange={(event) => {
emit('change-default', event); emit('change-default', event);
@ -133,41 +106,35 @@ export default createComponent({
watch( watch(
() => props.contactInfo, () => props.contactInfo,
(value) => { (value) => {
state.contact = { Object.assign(contact, DEFAULT_CONTACT, value);
...DEFAULT_CONTACT,
...value,
};
} }
); );
return () => { return () => (
const { contact, errorInfo } = state; <Form class={bem()} onSubmit={onSave}>
return (
<div class={bem()}>
<div class={bem('fields')}> <div class={bem('fields')}>
<Field <Field
vModel={contact.name} v-model={contact.name}
clearable clearable
maxlength="30"
label={t('name')} label={t('name')}
rules={[{ required: true, message: t('nameInvalid') }]}
maxlength="30"
placeholder={t('nameEmpty')} placeholder={t('nameEmpty')}
errorMessage={errorInfo.name}
onFocus={() => onFocus('name')}
/> />
<Field <Field
vModel={contact.tel} v-model={contact.tel}
clearable clearable
type="tel" type="tel"
label={t('tel')} label={t('tel')}
rules={[
{ validator: props.telValidator, message: t('telInvalid') },
]}
placeholder={t('telEmpty')} placeholder={t('telEmpty')}
errorMessage={errorInfo.tel}
onFocus={() => onFocus('tel')}
/> />
</div> </div>
{renderSetDefault()} {renderSetDefault()}
{renderButtons()} {renderButtons()}
</div> </Form>
); );
};
}, },
}); });

View File

@ -2,7 +2,7 @@
exports[`should render demo and match snapshot 1`] = ` exports[`should render demo and match snapshot 1`] = `
<div> <div>
<div class="van-contact-edit"> <form class="van-form van-contact-edit">
<div class="van-contact-edit__fields"> <div class="van-contact-edit__fields">
<div class="van-cell van-field"> <div class="van-cell van-field">
<div class="van-cell__title van-field__label"> <div class="van-cell__title van-field__label">
@ -51,7 +51,7 @@ exports[`should render demo and match snapshot 1`] = `
</div> </div>
</div> </div>
<div class="van-contact-edit__buttons"> <div class="van-contact-edit__buttons">
<button type="button" <button type="submit"
class="van-button van-button--danger van-button--normal van-button--block van-button--round" class="van-button van-button--danger van-button--normal van-button--block van-button--round"
> >
<div class="van-button__content"> <div class="van-button__content">
@ -70,6 +70,6 @@ exports[`should render demo and match snapshot 1`] = `
</div> </div>
</button> </button>
</div> </div>
</div> </form>
</div> </div>
`; `;

View File

@ -6,6 +6,12 @@ const contactInfo = {
tel: '13000000000', tel: '13000000000',
}; };
async function submitForm(wrapper) {
const form = wrapper.find('form');
await form.trigger('submit');
return later();
}
test('should validate contact name before submitting form', async () => { test('should validate contact name before submitting form', async () => {
const wrapper = mount(ContactEdit, { const wrapper = mount(ContactEdit, {
props: { props: {
@ -16,16 +22,8 @@ test('should validate contact name before submitting form', async () => {
}, },
}); });
const button = wrapper.find('.van-button'); await submitForm(wrapper);
button.trigger('click');
await later();
expect(wrapper.find('.van-field__error-message').html()).toMatchSnapshot(); expect(wrapper.find('.van-field__error-message').html()).toMatchSnapshot();
const fields = wrapper.findAll('.van-field__control');
fields[0].trigger('focus');
await later();
expect(wrapper.find('.van-field__error-message').exists()).toBeFalsy();
}); });
test('should validate contact tel before submitting form', async () => { test('should validate contact tel before submitting form', async () => {
@ -38,16 +36,8 @@ test('should validate contact tel before submitting form', async () => {
}, },
}); });
const button = wrapper.find('.van-button'); await submitForm(wrapper);
button.trigger('click');
await later();
expect(wrapper.find('.van-field__error-message').html()).toMatchSnapshot(); expect(wrapper.find('.van-field__error-message').html()).toMatchSnapshot();
const fields = wrapper.findAll('.van-field__control');
fields[1].trigger('focus');
await later();
expect(wrapper.find('.van-field__error-message').exists()).toBeFalsy();
}); });
test('should emit save event after submitting form', async () => { test('should emit save event after submitting form', async () => {
@ -57,19 +47,14 @@ test('should emit save event after submitting form', async () => {
}, },
}); });
const button = wrapper.find('.van-button'); await submitForm(wrapper);
button.trigger('click');
await later();
expect(wrapper.emitted('save')[0][0]).toEqual(contactInfo); expect(wrapper.emitted('save')[0][0]).toEqual(contactInfo);
}); });
test('should watch contact info', async () => { test('should watch contact info', async () => {
const wrapper = mount(ContactEdit); const wrapper = mount(ContactEdit);
const button = wrapper.find('.van-button'); await wrapper.setProps({ contactInfo });
await submitForm(wrapper);
wrapper.setProps({ contactInfo });
await later();
button.trigger('click');
expect(wrapper.emitted('save')[0][0]).toEqual(contactInfo); expect(wrapper.emitted('save')[0][0]).toEqual(contactInfo);
}); });