wot-design-uni
Version:
一个基于Vue3+TS开发的uni-app组件库,提供70+高质量组件,支持暗黑模式、国际化和自定义主题。
153 lines (144 loc) • 5.54 kB
text/typescript
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
}