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

View File

@ -2,7 +2,7 @@
exports[`should render demo and match snapshot 1`] = `
<div>
<div class="van-contact-edit">
<form class="van-form van-contact-edit">
<div class="van-contact-edit__fields">
<div class="van-cell van-field">
<div class="van-cell__title van-field__label">
@ -51,7 +51,7 @@ exports[`should render demo and match snapshot 1`] = `
</div>
</div>
<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"
>
<div class="van-button__content">
@ -70,6 +70,6 @@ exports[`should render demo and match snapshot 1`] = `
</div>
</button>
</div>
</div>
</form>
</div>
`;

View File

@ -6,6 +6,12 @@ const contactInfo = {
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 () => {
const wrapper = mount(ContactEdit, {
props: {
@ -16,16 +22,8 @@ test('should validate contact name before submitting form', async () => {
},
});
const button = wrapper.find('.van-button');
button.trigger('click');
await later();
await submitForm(wrapper);
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 () => {
@ -38,16 +36,8 @@ test('should validate contact tel before submitting form', async () => {
},
});
const button = wrapper.find('.van-button');
button.trigger('click');
await later();
await submitForm(wrapper);
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 () => {
@ -57,19 +47,14 @@ test('should emit save event after submitting form', async () => {
},
});
const button = wrapper.find('.van-button');
button.trigger('click');
await later();
await submitForm(wrapper);
expect(wrapper.emitted('save')[0][0]).toEqual(contactInfo);
});
test('should watch contact info', async () => {
const wrapper = mount(ContactEdit);
const button = wrapper.find('.van-button');
wrapper.setProps({ contactInfo });
await later();
button.trigger('click');
await wrapper.setProps({ contactInfo });
await submitForm(wrapper);
expect(wrapper.emitted('save')[0][0]).toEqual(contactInfo);
});