feat(all): ✨ 新增工具
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
import { isEqual } from "lodash-es";
|
||||
import { toRef, computed, watch } from "vue";
|
||||
import type { Ref } from "vue";
|
||||
|
||||
interface UsePickerOptions {
|
||||
/** 选中的值 */
|
||||
value?: unknown[] | Ref<unknown[]>;
|
||||
show?: boolean | Ref<boolean>;
|
||||
/** 选中的值 */
|
||||
indexes?: Array<number | null> | Ref<Array<number | null>>;
|
||||
columns?: UViewPlus.PickerColumns | Ref<UViewPlus.PickerColumns>;
|
||||
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,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user