types(AddressEdit): use tsx (#8141)

This commit is contained in:
neverland 2021-02-12 13:22:44 +08:00 committed by GitHub
parent a00f599dc2
commit 2fc8333c45
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 95 additions and 74 deletions

View File

@ -1,4 +1,4 @@
import { ref } from 'vue';
import { PropType, ref } from 'vue';
// Utils
import { createNamespace } from '../utils';
@ -11,14 +11,19 @@ import Field from '../field';
const [createComponent, bem, t] = createNamespace('address-edit-detail');
const android = isAndroid();
export type AddressEditSearchItem = {
name: string;
address: string;
};
export default createComponent({
props: {
show: Boolean,
value: String,
errorMessage: String,
focused: Boolean,
detailRows: [Number, String],
searchResult: Array,
searchResult: Array as PropType<AddressEditSearchItem[]>,
errorMessage: String,
detailMaxlength: [Number, String],
showSearchResult: Boolean,
},
@ -31,7 +36,7 @@ export default createComponent({
const showSearchResult = () =>
props.focused && props.searchResult && props.showSearchResult;
const onSelect = (express) => {
const onSelect = (express: AddressEditSearchItem) => {
emit('select-search', express);
emit('input', `${express.address || ''} ${express.name || ''}`.trim());
};
@ -50,10 +55,10 @@ export default createComponent({
}
};
const renderSearchTitle = (express) => {
const renderSearchTitle = (express: AddressEditSearchItem) => {
if (express.name) {
const text = express.name.replace(
props.value,
props.value!,
`<span class=${bem('keyword')}>${props.value}</span>`
);
@ -67,7 +72,7 @@ export default createComponent({
}
const { searchResult } = props;
return searchResult.map((express) => (
return searchResult!.map((express) => (
<Cell
v-slots={{
title: () => renderSearchTitle(express),
@ -85,15 +90,15 @@ export default createComponent({
));
};
const onFocus = (event) => {
const onFocus = (event: Event) => {
emit('focus', event);
};
const onBlur = (event) => {
const onBlur = (event: Event) => {
emit('blur', event);
};
const onInput = (value) => {
const onInput = (value: string) => {
emit('input', value);
};

View File

@ -123,8 +123,7 @@ Use [ref](https://v3.vuejs.org/guide/component-template-refs.html) to get Addres
### AddressInfo Data Structure
| key | Description | Type |
| ------------- | ------------------ | ------------------ |
| id | Address Id | _number \| string_ |
| ------------- | ------------------ | --------- |
| name | Name | _string_ |
| tel | Phone | _string_ |
| province | Province | _string_ |

View File

@ -126,18 +126,17 @@ export default {
### AddressInfo 数据格式
注意AddressInfo 仅作为初始值传入,表单最终内容可以在 save 事件中获取
注意:`AddressInfo` 仅作为初始值传入,表单最终内容可以在 save 事件中获取
| key | 说明 | 类型 |
| ------------- | -------------------------------------- | ------------------ |
| id | 每条地址的唯一标识 | _number \| string_ |
| --- | --- | --- |
| name | 收货人姓名 | _string_ |
| tel | 收货人手机号 | _string_ |
| province | 省份 | _string_ |
| city | 城市 | _string_ |
| county | 区县 | _string_ |
| addressDetail | 详细地址 | _string_ |
| areaCode | 地区编码,通过`省市区选择`获取(必填) | _string_ |
| areaCode | 地区编码,通过 [省市区选择](#/zh-CN/area) 获取(必填) | _string_ |
| postalCode | 邮政编码 | _string_ |
| isDefault | 是否为默认地址 | _boolean_ |

View File

@ -1,4 +1,4 @@
import { ref, watch, computed, nextTick, reactive } from 'vue';
import { ref, watch, computed, nextTick, reactive, PropType } from 'vue';
// Utils
import { createNamespace, isObject } from '../utils';
@ -8,45 +8,58 @@ import { isMobile } from '../utils/validate/mobile';
import { useExpose } from '../composables/use-expose';
// Components
import Area from '../area';
import Area, { AreaList, AreaColumnOption } from '../area';
import Cell from '../cell';
import Field from '../field';
import Popup from '../popup';
import Toast from '../toast';
import Button from '../button';
import Dialog from '../dialog';
import Detail from './Detail';
import Switch from '../switch';
import Detail, { AddressEditSearchItem } from './Detail';
const [createComponent, bem, t] = createNamespace('address-edit');
const defaultData = {
name: '',
tel: '',
country: '',
province: '',
city: '',
county: '',
areaCode: '',
postalCode: '',
addressDetail: '',
isDefault: false,
export type AddressInfo = {
tel: string;
name: string;
city: string;
county: string;
country: string;
province: string;
areaCode: string;
isDefault?: boolean;
postalCode?: string;
addressDetail: string;
};
function isPostal(value) {
const defaultData: AddressInfo = {
name: '',
tel: '',
city: '',
county: '',
country: '',
province: '',
areaCode: '',
isDefault: false,
postalCode: '',
addressDetail: '',
};
function isPostal(value: string) {
return /^\d{6}$/.test(value);
}
export default createComponent({
props: {
areaList: Object,
areaList: Object as PropType<AreaList>,
isSaving: Boolean,
isDeleting: Boolean,
validator: Function,
showDelete: Boolean,
showPostal: Boolean,
disableArea: Boolean,
searchResult: Array,
searchResult: Array as PropType<AddressEditSearchItem[]>,
telMaxlength: [Number, String],
showSetDefault: Boolean,
saveButtonText: String,
@ -70,19 +83,19 @@ export default createComponent({
default: 200,
},
addressInfo: {
type: Object,
type: Object as PropType<Partial<AddressInfo>>,
default: () => ({ ...defaultData }),
},
telValidator: {
type: Function,
type: Function as PropType<(val: string) => boolean>,
default: isMobile,
},
postalValidator: {
type: Function,
type: Function as PropType<(val: string) => boolean>,
default: isPostal,
},
areaColumnsPlaceholder: {
type: Array,
type: Array as PropType<string[]>,
default: () => [],
},
},
@ -103,7 +116,7 @@ export default createComponent({
const areaRef = ref();
const state = reactive({
data: {},
data: {} as AddressInfo,
showAreaPopup: false,
detailFocused: false,
errorInfo: {
@ -112,7 +125,7 @@ export default createComponent({
areaCode: '',
postalCode: '',
addressDetail: '',
},
} as Record<string, string>,
});
const areaListLoaded = computed(
@ -146,14 +159,14 @@ export default createComponent({
}
};
const onFocus = (key) => {
const onFocus = (key: string) => {
state.errorInfo[key] = '';
state.detailFocused = key === 'addressDetail';
emit('focus', key);
};
const getErrorMessage = (key) => {
const value = String(state.data[key] || '').trim();
const getErrorMessage = (key: string) => {
const value = String((state.data as any)[key] || '').trim();
if (props.validator) {
const message = props.validator(key, value);
@ -204,12 +217,12 @@ export default createComponent({
}
};
const onChangeDetail = (val) => {
const onChangeDetail = (val: string) => {
state.data.addressDetail = val;
emit('change-detail', val);
};
const onAreaConfirm = (values) => {
const onAreaConfirm = (values: AreaColumnOption[]) => {
values = values.filter((value) => !!value);
if (values.some((value) => !value.code)) {
@ -238,7 +251,7 @@ export default createComponent({
const getArea = () => (areaRef.value ? areaRef.value.getValues() : []);
// set area code to area component
const setAreaCode = (code) => {
const setAreaCode = (code?: string) => {
state.data.areaCode = code || '';
if (code) {
@ -253,7 +266,7 @@ export default createComponent({
});
};
const setAddressDetail = (value) => {
const setAddressDetail = (value: string) => {
state.data.addressDetail = value;
};
@ -262,7 +275,7 @@ export default createComponent({
const slots = {
'right-icon': () => (
<Switch
vModel={state.data.isDefault}
v-model={state.data.isDefault}
size="24"
onChange={(event) => {
emit('change-default', event);
@ -365,7 +378,7 @@ export default createComponent({
onBlur={onDetailBlur}
onFocus={() => onFocus('addressDetail')}
onInput={onChangeDetail}
onSelect-search={(event) => {
onSelect-search={(event: Event) => {
emit('select-search', event);
}}
/>
@ -404,7 +417,7 @@ export default createComponent({
)}
</div>
<Popup
vModel={[state.showAreaPopup, 'show']}
v-model={[state.showAreaPopup, 'show']}
round
teleport="body"
position="bottom"

View File

@ -18,7 +18,7 @@ import { createNamespace, pick } from '../utils';
import { useExpose } from '../composables/use-expose';
// Components
import Picker, { PickerObjectOption } from '../picker';
import Picker from '../picker';
import { pickerProps } from '../picker/shared';
const [createComponent, bem] = createNamespace('area');
@ -35,6 +35,11 @@ export type AreaList = {
province_list: Record<string, string>;
};
export type AreaColumnOption = {
name: string;
code: string;
};
type ColumnType = 'province' | 'county' | 'city';
export default createComponent({
@ -109,7 +114,7 @@ export default createComponent({
};
const getColumnValues = (type: ColumnType, code?: string) => {
let column: PickerObjectOption[] = [];
let column: AreaColumnOption[] = [];
if (type !== 'province' && !code) {
return column;
}
@ -202,7 +207,7 @@ export default createComponent({
};
// parse output columns data
const parseValues = (values: PickerObjectOption[]) => {
const parseValues = (values: AreaColumnOption[]) => {
return values.map((value, index) => {
if (value) {
value = deepClone(value);
@ -221,7 +226,7 @@ export default createComponent({
if (pickerRef.value) {
const values = pickerRef.value
.getValues()
.filter((value: PickerObjectOption) => !!value);
.filter((value: AreaColumnOption) => !!value);
return parseValues(values);
}
return [];
@ -265,7 +270,7 @@ export default createComponent({
setValues();
};
const onChange = (values: PickerObjectOption[], index: number) => {
const onChange = (values: AreaColumnOption[], index: number) => {
state.code = values[index].code;
setValues();
@ -273,7 +278,7 @@ export default createComponent({
emit('change', parsedValues, index);
};
const onConfirm = (values: PickerObjectOption[], index: number) => {
const onConfirm = (values: AreaColumnOption[], index: number) => {
setValues();
emit('confirm', parseValues(values), index);
};