import produce, { Draft, enableES5 } from 'immer'; import { isValue } from '../../utils/lang'; export interface Value { /** 数据的唯一标示 */ value: string | number | boolean; /** 数据的唯一标示 */ id?: string | number | boolean; [key: string]: any; } export interface BaseProps { /** 是否禁用 */ disabled?: boolean; /** 是否多选 */ multiple?: boolean; /** 只有1个选项并且可以开关时启用 */ switch?: boolean; /** 最多可选数量 */ max?: number; /** 渲染的数据 */ data: T[]; } export type OnChange = (value: T[], item: T, index: number) => boolean; function isEquals(a: T, b: T) { if (isValue(a.id) && isValue(b.id)) { return a.id === b.id; } return a.value === b.value; } /** 用于更新props value */ function createNewValue(props: BaseProps, value: T[], nextValue: T): T[] { const { multiple } = props; if (multiple) { // 多选 const index = value.findIndex((item) => isEquals(item, nextValue)); return produce(value, (draft) => { if (index >= 0) { draft.splice(index, 1); } else { draft.push(nextValue as Draft); } }); } else if (props.switch) { // 如果开启了switch,就会有勾选或取消勾选的功能 if (value[0]) { return isEquals(value[0], nextValue) ? [] : [nextValue]; } return [nextValue]; } else { // 单选 return [nextValue]; } } export function onClick(props: BaseProps, params: { onChange: OnChange; item: T; index: number; value: T[]; }): boolean { const { disabled, multiple, max } = props; const { value, index, onChange, item } = params; if (disabled) { return false; } const valueFirst = value[0]; // 防止重复点击 if (multiple !== true && props.switch !== true && valueFirst && isEquals(valueFirst, item)) { return false; } if (((max && value.length < max) || (max === undefined || max === 0))) { const newValue = createNewValue(props, value, item); // 小于max数量时 if (onChange) { onChange(newValue, item, index); } } return true; // else if (value && (max && value.size >= max) && value.findIndex((item) => item.id === nextValueFirst.id) >= 0) { // // 超过max数量时,将 // callbackOnClick(event, this.createNewValue(nextValue[0]), index); // } } export function getState(value: Value[], required?: boolean) { const isEmpty = value.length === 0 || ( value[0] && (!isValue(value[0].id) || !isValue(value[0].value)) ); return isEmpty && required ? 'empty' : 'complete'; } export function immerEnableES5() { enableES5(); }