mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
types(AddressEdit): use tsx (#8141)
This commit is contained in:
parent
a00f599dc2
commit
2fc8333c45
@ -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);
|
||||
};
|
||||
|
@ -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_ |
|
||||
|
@ -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_ |
|
||||
|
||||
|
@ -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"
|
@ -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);
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user