mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-05-22 22:49:15 +08:00
refactor(ContactEdit): refactor with composition api
This commit is contained in:
parent
ee256e591c
commit
4f0921cbdf
@ -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>
|
||||||
|
);
|
||||||
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user