refactor(ContactEdit): refactor with composition api

This commit is contained in:
chenjiahan 2020-09-21 19:08:27 +08:00
parent ee256e591c
commit 4f0921cbdf

View File

@ -1,3 +1,5 @@
import { watch, reactive } from 'vue';
// Utils // Utils
import { createNamespace } from '../utils'; import { createNamespace } from '../utils';
import { isMobile } from '../utils/validate/mobile'; import { isMobile } from '../utils/validate/mobile';
@ -11,7 +13,7 @@ import Switch from '../switch';
const [createComponent, bem, t] = createNamespace('contact-edit'); const [createComponent, bem, t] = createNamespace('contact-edit');
const defaultContact = { const DEFAULT_CONTACT = {
tel: '', tel: '',
name: '', name: '',
}; };
@ -25,7 +27,7 @@ export default createComponent({
setDefaultLabel: String, setDefaultLabel: String,
contactInfo: { contactInfo: {
type: Object, type: Object,
default: () => ({ ...defaultContact }), default: () => ({ ...DEFAULT_CONTACT }),
}, },
telValidator: { telValidator: {
type: Function, type: Function,
@ -35,130 +37,137 @@ export default createComponent({
emits: ['save', 'delete', 'change-default'], emits: ['save', 'delete', 'change-default'],
data() { setup(props, { emit }) {
return { const state = reactive({
data: { contact: {
...defaultContact, ...DEFAULT_CONTACT,
...this.contactInfo, ...props.contactInfo,
}, },
errorInfo: { errorInfo: {
name: '', name: '',
tel: '', tel: '',
}, },
});
const onFocus = (key) => {
state.errorInfo[key] = '';
}; };
},
watch: { const getErrorMessageByKey = (key) => {
contactInfo(val) { const value = state.contact[key].trim();
this.data = {
...defaultContact,
...val,
};
},
},
methods: {
onFocus(key) {
this.errorInfo[key] = '';
},
getErrorMessageByKey(key) {
const value = this.data[key].trim();
switch (key) { switch (key) {
case 'name': case 'name':
return value ? '' : t('nameInvalid'); return value ? '' : t('nameInvalid');
case 'tel': case 'tel':
return this.telValidator(value) ? '' : t('telInvalid'); return props.telValidator(value) ? '' : t('telInvalid');
} }
}, };
onSave() { const onSave = () => {
const isValid = ['name', 'tel'].every((item) => { const isValid = ['name', 'tel'].every((item) => {
const msg = this.getErrorMessageByKey(item); const msg = getErrorMessageByKey(item);
if (msg) { if (msg) {
this.errorInfo[item] = msg; state.errorInfo[item] = msg;
} }
return !msg; return !msg;
}); });
if (isValid && !this.isSaving) { if (isValid && !props.isSaving) {
this.$emit('save', this.data); emit('save', state.contact);
} }
}, };
onDelete() { const onDelete = () => {
Dialog.confirm({ Dialog.confirm({
title: t('confirmDelete'), title: t('confirmDelete'),
}).then(() => { }).then(() => {
this.$emit('delete', this.data); emit('delete', state.contact);
}); });
}, };
},
render() { const renderButtons = () => (
const { data, errorInfo } = this; <div class={bem('buttons')}>
const onFocus = (name) => () => this.onFocus(name); <Button
block
return ( round
<div class={bem()}> type="danger"
<div class={bem('fields')}> text={t('save')}
<Field loading={props.isSaving}
vModel={data.name} onClick={onSave}
clearable />
maxlength="30" {props.isEdit && (
label={t('name')}
placeholder={t('nameEmpty')}
errorMessage={errorInfo.name}
onFocus={onFocus('name')}
/>
<Field
vModel={data.tel}
clearable
type="tel"
label={t('tel')}
placeholder={t('telEmpty')}
errorMessage={errorInfo.tel}
onFocus={onFocus('tel')}
/>
</div>
{this.showSetDefault && (
<Cell
v-slots={{
'right-icon': () => (
<Switch
vModel={data.isDefault}
size={24}
onChange={(event) => {
this.$emit('change-default', event);
}}
/>
),
}}
title={this.setDefaultLabel}
class={bem('switch-cell')}
border={false}
></Cell>
)}
<div class={bem('buttons')}>
<Button <Button
block block
round round
type="danger" text={t('delete')}
text={t('save')} loading={props.isDeleting}
loading={this.isSaving} onClick={onDelete}
onClick={this.onSave}
/> />
{this.isEdit && ( )}
<Button
block
round
text={t('delete')}
loading={this.isDeleting}
onClick={this.onDelete}
/>
)}
</div>
</div> </div>
); );
const renderSwitch = () => (
<Switch
vModel={state.contact.isDefault}
size={24}
onChange={(event) => {
emit('change-default', event);
}}
/>
);
const renderSetDefault = () => {
if (props.showSetDefault) {
return (
<Cell
v-slots={{ 'right-icon': renderSwitch }}
title={props.setDefaultLabel}
class={bem('switch-cell')}
border={false}
/>
);
}
};
watch(
() => props.contactInfo,
(value) => {
state.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()}
</div>
);
};
}, },
}); });