UNPKG

wot-design-uni

Version:

一个基于Vue3+TS开发的uni-app组件库,提供70+高质量组件,支持暗黑模式、国际化和自定义主题。

153 lines (144 loc) 5.54 kB
import type { ComponentPublicInstance, ExtractPropTypes, PropType, Ref } from 'vue' import { baseProps, makeArrayProp, makeBooleanProp, makeNumberProp, makeStringProp } from '../common/props' import { getType, isArray, isObj } from '../common/util' export type ColumnItem = { [key: string]: any value?: string | number | boolean label?: string disabled?: boolean } export type PickerViewColumnChange = ( pickerView: PickerViewInstance, selects: Record<string, any> | Record<string, any>[], index: number, reslove: () => void ) => void export const pickerViewProps = { ...baseProps, /** * 加载状态 */ loading: makeBooleanProp(false), /** * 加载的颜色,只能使用十六进制的色值写法,且不能使用缩写 */ loadingColor: makeStringProp('#4D80F0'), /** * picker内部滚筒高 */ columnsHeight: makeNumberProp(217), /** * picker item的高度 */ itemHeight: makeNumberProp(35), /** * 选项对象中,value对应的 key */ valueKey: makeStringProp('value'), /** * 选项对象中,展示的文本对应的 key */ labelKey: makeStringProp('label'), /** * 是否在手指松开时立即触发picker-view的 change 事件。若不开启则会在滚动动画结束后触发 change 事件,1.2.25版本起提供,仅微信小程序和支付宝小程序支持。 */ immediateChange: makeBooleanProp(false), /** * 选中项,如果为多列选择器,则其类型应为数组 */ modelValue: { type: [String, Number, Boolean, Array<number>, Array<string>, Array<boolean>] as PropType< string | number | boolean | Array<number> | Array<string> | Array<boolean> >, default: '', required: true }, /** * 选择器数据,可以为字符串数组,也可以为对象数组,如果为二维数组,则为多列选择器 */ columns: makeArrayProp<string | number | ColumnItem | Array<number> | Array<string> | Array<ColumnItem>>(), /** * 接收 pickerView 实例、选中项、当前修改列的下标、resolve 作为入参,根据选中项和列下标进行判断,通过 pickerView 实例暴露出来的 setColumnData 方法修改其他列的数据源。 */ columnChange: Function as PropType<PickerViewColumnChange> } export type PickerViewExpose = { getSelects: () => Record<string, any> | Record<string, any>[] getValues: () => string | string[] setColumnData: (columnIndex: number, data: Array<string | number | ColumnItem | Array<string | number | ColumnItem>>, rowIndex?: number) => void getColumnsData: () => Record<string, string>[][] getColumnData: (columnIndex: number) => Record<string, string>[] getColumnIndex: (columnIndex: number) => number getLabels: () => string[] getSelectedIndex: () => number[] resetColumns: (columns: (string | number | string[] | number[] | ColumnItem | ColumnItem[])[]) => void } export type PickerViewProps = ExtractPropTypes<typeof pickerViewProps> export type PickerViewInstance = ComponentPublicInstance<PickerViewProps, PickerViewExpose> /** * 格式化传入的列数据 * 列数据统一格式化为二维数组 * @param array 列数据 * @param valueKey * @param labelKey * @returns */ export function formatArray( array: Array<string | number | ColumnItem | Array<string | number | ColumnItem>>, valueKey: string, labelKey: string ): ColumnItem[][] { let tempArray: Array<string | number | ColumnItem | Array<string | number | ColumnItem>> = isArray(array) ? array : [array] // 判断数组第一层的数据类型,如果存在多种类型,则抛错 const firstLevelTypeList = new Set(array.map(getType)) /** * 存在三种类型的合法数据 * 1.数组是一维元素,所有元素都是原始值 * 2.数组是一维元素,所有元素都是object * 3.数组是二维元素,二维元素可以是任意内容 */ if (firstLevelTypeList.size !== 1 && firstLevelTypeList.has('object')) { // 原始值和引用类型不用混用 throw Error('The columns are correct') } /** * 简单处理,如果数组第一项不是数组则认为它是一个一维数组 * 所以需要把一维的转成二维,这样方便统一处理 */ if (!isArray(array[0])) { tempArray = [tempArray as Array<string | number | ColumnItem>] } // 转化为二维数组后需要将每一项包装成ColumnItem const result: Array<Array<ColumnItem>> = (tempArray as Array<Array<string | number | ColumnItem>>).map((col) => { return col.map((row) => { // 非对象类型直接将值作为label和value if (!isObj(row)) { return { [valueKey]: row, [labelKey]: row } } /** * 针对已经是object的,修补成{valueKey,labelKey} * 如果没有labelKey,用valueKey代替 * 如果没有valueKey,用labelKey代替 * valueKey,labelKey都没有,直接抛错 */ // eslint-disable-next-line no-prototype-builtins if (!row.hasOwnProperty(valueKey) && !row.hasOwnProperty(labelKey)) { // eslint-disable-next-line prettier/prettier throw Error('Can\'t find valueKey and labelKey in columns') } // eslint-disable-next-line no-prototype-builtins if (!row.hasOwnProperty(labelKey)) { row[labelKey] = row[valueKey] } // eslint-disable-next-line no-prototype-builtins if (!row.hasOwnProperty(valueKey)) { row[valueKey] = row[labelKey] } return row }) }) return result }