| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- <template>
- <a-cascader
- :value="value"
- :options="options"
- :load-data="doLoadData"
- :placeholder="placeholder"
- @update:value="onUpdateValue"
- change-on-select
- v-bind="(customProps as any)"
- />
- </template>
- <script lang="ts">
- import { defineComponent, onMounted, type PropType, ref, toRefs, watch } from "vue";
- import type { CascaderProps } from "ant-design-vue";
- import type { LoadDataFun, OnChooseFun } from "./CascaderFormItem";
- export default defineComponent({
- props: {
- loadData: {
- type: Function as PropType<LoadDataFun>,
- default: null,
- },
- placeholder: {
- type: String,
- default: '请选择地址',
- },
- loadAtStart: {
- type: Boolean,
- default: true,
- },
- loadCascaderToCurrentValueAtStart: {
- type: Boolean,
- default: true,
- },
- value: {},
- /**
- * 选择后回调
- */
- onSelect: {
- type: Function as PropType<OnChooseFun>,
- default: null,
- },
- onSelectFindIdKey: {
- type: String,
- default: 'id',
- },
- /**
- * a-cascader 其他自定义参数
- */
- customProps: {
- //type: Object as PropType<CascaderProps>,
- default: null,
- },
- },
- emits: [
- 'update:value'
- ],
- setup(props, context) {
- const { loadAtStart, loadCascaderToCurrentValueAtStart, value, loadData, onSelect } = toRefs(props);
- const options = ref<CascaderProps['options']>([]);
- const doLoadData = ((selectedOptions) => {
- const parent = selectedOptions && selectedOptions.length > 0 ? selectedOptions[selectedOptions.length - 1] : null;
- loadData.value(parent?.value as number, selectedOptions ? selectedOptions.length : 0, parent)
- .then((d) => {
- if (!d)
- throw new Error("loadData return invalid data!");
- if (parent) {
- //添加数据至指定层级下方
- if (!parent.children)
- parent.children = d;
- else
- parent.children = parent.children.concat(d);
- } else {
- //添加数据
- options.value = d;
- //这个时候加载一下默认选择项目
- if (loadCascaderToCurrentValueAtStart.value)
- doLoadDataToCurrentValue();
- }
- }).catch((e) => {
- console.error(e);
- });
- }) as CascaderProps['loadData'];
- function onUpdateValue(v: number[]) {
- context.emit('update:value', v);
- //选中后回调
- if (typeof onSelect.value === 'function') {
- const objArr = [] as unknown[];
- const valueArrNow = v.concat();
- //通过ID查找指定的对象
- let optionsCurrent = options.value as CascaderProps['options'];
- for (let i = 0; i < v.length; i++) {
- if (!optionsCurrent)
- break;
- const item = optionsCurrent.find(k => k.value === valueArrNow[i]);
- if (item) {
- objArr.push(item);
- optionsCurrent = item.children;//下一级
- } else {
- break;
- }
- }
- //回调
- onSelect.value(v, objArr);
- }
- }
- //加载树形数据至当前选中层级
- function doLoadDataToCurrentValue() {
- const valueArrNow = (value.value as number[]).concat();
- function findChildren(index: number, optionsCurrent: CascaderProps['options']) {
- if (!optionsCurrent)
- return;
- //当前级数据,查找是否存在,
- const option = optionsCurrent.find(k => k.value === valueArrNow[index]);
- if (option && (!option.children || option.children.length === 0)) {
- //存在,尝试加载下一级数据
- loadData.value(valueArrNow[index], index, option)
- .then((d) => {
- if (!d)
- throw new Error("loadData return invalid data!");
- if (parent) {
- if (!option.children)
- option.children = d;
- else
- option.children = option.children.concat(d);
-
- //如果还没有达到输入选择的层级,则进行下一次加载
- if (index < valueArrNow.length - 1) {
- findChildren(index + 1, option.children);
- }
- }
- }).catch((e) => {
- console.error(e);
- });
- }
- }
- findChildren(0, options.value);
- }
- onMounted(() => {
- if (loadAtStart.value && typeof doLoadData === 'function')
- doLoadData([]);
- });
- watch(value, () => {
- doLoadDataToCurrentValue();
- });
- return {
- doLoadData,
- doLoadDataToCurrentValue,
- onUpdateValue,
- options,
- };
- },
- });
- </script>
|