yanzhen-design-vue
Version:
137 lines (136 loc) • 4.83 kB
JavaScript
import { ref, reactive, unref, computed } from "vue";
import { isFunction } from "lodash-es";
import { isNumeral, isEmptyArray, isEmptyValue } from "@yanzhen-libs/utils";
import { useModelValue, useOptionKey, option } from "@yanzhen-libs/utils-vue";
import "../constants/index.mjs";
import { provideCascaderAreaApi } from "./use-cascader-area-apis.mjs";
import { useCascaderOptions } from "./use-cascader-options.mjs";
import { cascaderOptionType } from "../constants/option.mjs";
const provinceData = ref([]);
const cityData = reactive({});
const districtData = reactive({});
function useCascaderArea(props, emit) {
const modelValue = useModelValue(props, null, emit);
const { getAreaList } = provideCascaderAreaApi(props);
const cascaderOptions = useCascaderOptions(props);
const optionKey = useOptionKey([...cascaderOptionType]);
function handleOptionsProxy(target, mode = "city") {
const { value: valueKey, children: childrenKey } = unref(optionKey);
const map = option.toOptionsMap(unref(cascaderOptions));
return new Proxy(target, {
get(target2, p, receiver) {
const value = Reflect.get(target2, p, receiver);
if (isNumeral(p)) {
return new Proxy(value, {
get(target3, p2, receiver2) {
var _a;
const pid = target3[valueKey];
if (childrenKey === p2) {
let children;
switch (mode) {
case "city":
children = cityData[pid];
if (!isEmptyArray(children)) {
return handleOptionsProxy(children, "district");
}
break;
case "district":
children = districtData[pid];
break;
}
if (isEmptyArray(children) && !isEmptyValue(map == null ? void 0 : map[pid])) {
switch (props.mode) {
case "province": {
return [];
}
case "city": {
if (mode === "district") return [];
break;
}
default: {
return ((_a = map == null ? void 0 : map[pid]) == null ? void 0 : _a[childrenKey]) ?? children;
}
}
}
return children;
}
return Reflect.get(target3, p2, receiver2);
}
});
}
return value;
}
});
}
const options = computed(() => {
const optionsData = unref(provinceData);
if (isEmptyArray(optionsData)) {
return unref(cascaderOptions);
}
return handleOptionsProxy(optionsData);
});
function handleAreaTransform([id, ...ids], children = unref(options)) {
const { value: valueKey, children: childrenKey } = unref(optionKey);
if (isEmptyArray(children)) return [];
const find = children.find((item) => id === item[valueKey]);
const selectedOptions = !isEmptyValue(find) ? [find] : [];
const chids = find == null ? void 0 : find[childrenKey];
if (find && !isEmptyArray(chids)) {
const items = handleAreaTransform(ids, chids);
return selectedOptions.concat(items);
}
return selectedOptions;
}
const handleLoadData = async (selectedOptions) => {
if (isFunction(props.loadData)) {
return props.loadData(selectedOptions);
}
const option2 = selectedOptions[selectedOptions.length - 1];
const level = selectedOptions.length;
const pid = String((option2 == null ? void 0 : option2.value) ?? -1);
const result = await getAreaList({
data: {
mode: props.mode,
pid: option2 == null ? void 0 : option2.value,
values: selectedOptions
}
});
if ((result == null ? void 0 : result.code) === 0) {
const list = !isEmptyArray(result.data) ? result.data : [];
switch (level) {
case 2:
districtData[pid] = list;
break;
case 1:
cityData[pid] = list;
break;
default:
provinceData.value = list;
}
}
};
const handleVisibleChange = async (visible) => {
if (isEmptyArray(unref(provinceData)) && visible === true) {
const value = unref(modelValue);
const selectedOptions = handleAreaTransform(value ?? []);
if (selectedOptions.length > 0) {
while (selectedOptions.length > 0) {
selectedOptions.pop();
handleLoadData(selectedOptions);
}
} else {
handleLoadData([]);
}
}
emit("dropdownVisibleChange", visible);
};
return {
options,
handleLoadData,
handleVisibleChange,
handleAreaTransform
};
}
export {
useCascaderArea
};