types(Area): use tsx (#8140)

This commit is contained in:
neverland 2021-02-12 13:18:13 +08:00 committed by GitHub
parent 54be2b3c0a
commit a00f599dc2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 83 additions and 52 deletions

View File

@ -92,9 +92,9 @@ To have a selected valuesimply pass the `code` of target area to `value` prop
Use [ref](https://v3.vuejs.org/guide/component-template-refs.html) to get Area instance and call instance methods.
| Name | Description | Attribute | Return value |
| ----- | ------------------------- | ------------- | ------------ |
| reset | Reset all options by code | code?: string | - |
| Name | Description | Attribute | Return value |
| ----- | ------------------------- | --------------- | ------------ |
| reset | Reset all options by code | _code?: string_ | - |
### areaList Data Structure

View File

@ -94,7 +94,7 @@ app.use(Area);
| 方法名 | 说明 | 参数 | 返回值 |
| --- | --- | --- | --- |
| reset | 根据 code 重置所有选项,若不传 code则重置到第一项 | code?: string | - |
| reset | 根据 code 重置所有选项,若不传 code则重置到第一项 | _code?: string_ | - |
### 省市区列表数据格式

View File

@ -1,27 +1,48 @@
import { ref, watch, computed, reactive, nextTick, onMounted } from 'vue';
/* eslint-disable camelcase */
import {
ref,
watch,
computed,
reactive,
nextTick,
PropType,
onMounted,
ComponentPublicInstance,
} from 'vue';
// Utils
import { deepClone } from '../utils/deep-clone';
import { createNamespace, pick } from '../utils';
// Composition
import { useExpose } from '../composables/use-expose';
// Components
import Picker, { PickerObjectOption } from '../picker';
import { pickerProps } from '../picker/shared';
import Picker from '../picker';
const [createComponent, bem] = createNamespace('area');
const EMPTY_CODE = '000000';
function isOverseaCode(code) {
function isOverseaCode(code: string) {
return code[0] === '9';
}
function clone(obj) {
return JSON.parse(JSON.stringify(obj));
}
export type AreaList = {
city_list: Record<string, string>;
county_list: Record<string, string>;
province_list: Record<string, string>;
};
type ColumnType = 'province' | 'county' | 'city';
export default createComponent({
props: {
...pickerProps,
value: String,
areaList: {
type: Object,
type: Object as PropType<AreaList>,
default: () => ({}),
},
columnsNum: {
@ -29,11 +50,11 @@ export default createComponent({
default: 3,
},
isOverseaCode: {
type: Function,
type: Function as PropType<(code: string) => boolean>,
default: isOverseaCode,
},
columnsPlaceholder: {
type: Array,
type: Array as PropType<string[]>,
default: () => [],
},
},
@ -41,7 +62,8 @@ export default createComponent({
emits: ['change', 'confirm'],
setup(props, { emit, slots }) {
const pickerRef = ref();
// eslint-disable-next-line
const pickerRef = ref<ComponentPublicInstance<{}, any>>();
const state = reactive({
code: props.value,
@ -86,15 +108,14 @@ export default createComponent({
return '';
};
// get list by code
const getList = (type, code) => {
let result = [];
const getColumnValues = (type: ColumnType, code?: string) => {
let column: PickerObjectOption[] = [];
if (type !== 'province' && !code) {
return result;
return column;
}
const list = areaList.value[type];
result = Object.keys(list).map((listCode) => ({
column = Object.keys(list).map((listCode) => ({
code: listCode,
name: list[listCode],
}));
@ -104,10 +125,10 @@ export default createComponent({
if (type === 'city' && props.isOverseaCode(code)) {
code = '9';
}
result = result.filter((item) => item.code.indexOf(code) === 0);
column = column.filter((item) => item.code.indexOf(code!) === 0);
}
if (placeholderMap.value[type] && result.length) {
if (placeholderMap.value[type] && column.length) {
// set columns placeholder
let codeFill = '';
if (type === 'city') {
@ -116,17 +137,17 @@ export default createComponent({
codeFill = EMPTY_CODE.slice(4, 6);
}
result.unshift({
column.unshift({
code: code + codeFill,
name: placeholderMap.value[type],
});
}
return result;
return column;
};
// get index by code
const getIndex = (type, code) => {
const getIndex = (type: ColumnType, code: string) => {
let compareNum = code.length;
if (type === 'province') {
compareNum = props.isOverseaCode(code) ? 1 : 2;
@ -137,7 +158,7 @@ export default createComponent({
code = code.slice(0, compareNum);
const list = getList(
const list = getColumnValues(
type,
compareNum > 2 ? code.slice(0, compareNum - 2) : ''
);
@ -152,14 +173,10 @@ export default createComponent({
};
const setValues = () => {
let { code } = state;
if (!code) {
code = getDefaultCode();
}
let code = state.code || getDefaultCode();
const picker = pickerRef.value;
const province = getList('province');
const city = getList('city', code.slice(0, 2));
const province = getColumnValues('province');
const city = getColumnValues('city', code.slice(0, 2));
if (!picker) {
return;
@ -176,7 +193,7 @@ export default createComponent({
[{ code }] = city;
}
picker.setColumnValues(2, getList('county', code.slice(0, 4)));
picker.setColumnValues(2, getColumnValues('county', code.slice(0, 4)));
picker.setIndexes([
getIndex('province', code),
getIndex('city', code),
@ -185,10 +202,10 @@ export default createComponent({
};
// parse output columns data
const parseValues = (values) => {
const parseValues = (values: PickerObjectOption[]) => {
return values.map((value, index) => {
if (value) {
value = clone(value);
value = deepClone(value);
if (!value.code || value.name === props.columnsPlaceholder[index]) {
value.code = '';
@ -202,7 +219,9 @@ export default createComponent({
const getValues = () => {
if (pickerRef.value) {
const values = pickerRef.value.getValues().filter((value) => !!value);
const values = pickerRef.value
.getValues()
.filter((value: PickerObjectOption) => !!value);
return parseValues(values);
}
return [];
@ -246,15 +265,15 @@ export default createComponent({
setValues();
};
const onChange = (values, index) => {
const onChange = (values: PickerObjectOption[], index: number) => {
state.code = values[index].code;
setValues();
const parsedValues = parseValues(pickerRef.value.getValues());
const parsedValues = parseValues(pickerRef.value!.getValues());
emit('change', parsedValues, index);
};
const onConfirm = (values, index) => {
const onConfirm = (values: PickerObjectOption[], index: number) => {
setValues();
emit('confirm', parseValues(values), index);
};

View File

@ -29,14 +29,14 @@ function getElementTranslateY(element: Element) {
return Number(translateY);
}
export type PickerOption =
| string
| {
text: string;
disabled?: boolean;
// for custom filed names
[key: string]: any;
};
export type PickerObjectOption = {
text?: string;
disabled?: boolean;
// for custom filed names
[key: string]: any;
};
export type PickerOption = string | PickerObjectOption;
export type PickerObjectColumn = {
values?: PickerOption[];

View File

@ -12,9 +12,10 @@ import { useExpose } from '../composables/use-expose';
// Components
import Loading from '../loading';
import Column, {
PickerOption,
PickerColumn,
PickerOption,
PickerObjectColumn,
PickerObjectOption,
} from './PickerColumn';
const [createComponent, bem, t] = createNamespace('picker');
@ -27,6 +28,13 @@ export type PickerFieldNames = {
children?: string;
};
export type {
PickerColumn,
PickerOption,
PickerObjectColumn,
PickerObjectOption,
};
export default createComponent({
props: {
...pickerProps,

12
src/vue-tsx-shim.d.ts vendored
View File

@ -2,18 +2,22 @@ import 'vue';
type EventHandler = (...args: any[]) => void;
// TODO
// should be removed after Vue supported component events typing
// see: https://github.com/vuejs/vue-next/issues/1553
// https://github.com/vuejs/vue-next/issues/3029
declare module 'vue' {
interface ComponentCustomProps {
role?: string;
tabindex?: number;
// should be removed after Vue supported component events typing
// see: https://github.com/vuejs/vue-next/issues/1553
// https://github.com/vuejs/vue-next/issues/3029
onBlur?: EventHandler;
onFocus?: EventHandler;
onInput?: EventHandler;
onClick?: EventHandler;
onCancel?: EventHandler;
onClosed?: EventHandler;
onChange?: EventHandler;
onToggle?: EventHandler;
onConfirm?: EventHandler;
onClickStep?: EventHandler;
}
}