UNPKG

yanzhen-design-vue

Version:

137 lines (136 loc) 4.83 kB
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 };