import { isEqual } from "lodash-es"; import { toRef, computed, watch } from "vue"; import type { Ref } from "vue"; interface UsePickerOptions { /** 选中的值 */ value?: unknown[] | Ref; show?: boolean | Ref; /** 选中的值 */ indexes?: Array | Ref>; columns?: UViewPlus.PickerColumns | Ref; textName?: string; valueName?: string; placeholder?: string; separator?: string; } /** * 多列 picker * @param options 选项 * @returns */ export function usePicker(options: UsePickerOptions) { const value = toRef(options.value ?? []); const show = toRef(options.show ?? false); const indexes = toRef(options.indexes ?? []); const columns = toRef(options.columns ?? [[]]); const textName = toRef(options.textName ?? "text"); const valueName = toRef(options.valueName ?? "value"); const placeholder = toRef(options.placeholder ?? "请选择"); const separator = toRef(options.separator ?? " "); const text = computed(() => { const textArray = indexes.value.map((i, index) => { if (i == null) return null; const item = columns.value[index][i]; return item?.[textName.value] ?? null; }); if (textArray.some((v) => v == null)) { return placeholder.value; } return textArray.join(separator.value); }); // 监听 indexes 变化,更新 value watch( [indexes, columns], ([newIndexes, newColumns]) => { console.log("indexes changed:", newIndexes, newColumns); if (!newIndexes.length) return; const newValue = newIndexes.map((index, columnIndex) => { if (index == null) return null; const item = newColumns[columnIndex]?.[index]; return item?.[valueName.value] ?? null; }); if (!isEqual(newValue, value.value)) { value.value = newValue; } }, { immediate: true, deep: true }, ); // 监听 value 变化,更新 indexes watch( [value, columns], ([newValue, newColumns]) => { console.log("value changed:", newValue, newColumns); const newIndexes = newColumns.map((column, columnIndex) => { const index = column.findIndex( (item) => item[valueName.value] === newValue?.[columnIndex], ); return index >= 0 ? index : null; }); if (!isEqual(newIndexes, indexes.value)) { indexes.value = newIndexes; } }, { immediate: true, deep: true }, ); function handleConfirm(e: UViewPlus.PickerConfirmEvent) { console.log("handleConfirm:", e); indexes.value = e.indexs; } function columnValueToText(v: unknown, colIndex = 0) { const currentItem = columns.value[colIndex].find( (item) => item[valueName.value] === v, ); return currentItem?.[textName.value]; } function valueToText(v: unknown[]) { return v.map((item, index) => columnValueToText(item, index)); } function showPicker() { show.value = true; } function hidePicker() { show.value = false; } return { text, value, indexes, columns, handleConfirm, valueToText, columnValueToText, textName, valueName, show, showPicker, hidePicker, }; }