由于es6支持哈希,所以数据量只要不太大,就不需要对el-cascader进行点击后在调接口出现下一级,很简单的就是直接获取所有数据。
<template>
<div>
<el-cascader :modelValue="modelValue" :props="innerProps" :options="options" @change="handleChange" filterable
:show-all-levels="showAllLevels" :disabled="disabled" :placeholder="placeholder" :clearable="clearable"
style="width:100%" @blur="onBlur" @focus="onFocus" @close="handleClose" @visible-change="onVisibleChange" />
<!-- --- {{ modelValue }} -->
</div>
</template>
<script lang="ts" setup>
import { ref, reactive, toRaw, onMounted, watch, onBeforeUnmount } from 'vue'
import type { CascaderProps } from 'element-plus'
import * as api from "./api.js";
const props = defineProps({
modelValue: {
type: Array,
default: []
},
// 是否支持清空选项
clearable: {
type: Boolean,
default: true,
},
// 是否多选
// multiple: {
// type: Boolean,
// default: false,
// },
// 指定某省,传入该自治区的areacode
designation: {
type: String,
default: '',
},
// 仅显示最后一级
showAllLevels: {
type: Boolean,
default: true,
},
// 是否禁用
disabled: {
type: Boolean,
default: false,
},
// 输入框占位文本
placeholder: {
type: String,
default: '',
},
// 是否选择任意一级选项,还是最后叶子结点
checkStrictly: {
type: Boolean,
default: true,
},
// 次级菜单的展开方式,click和hover
expandTrigger: {
type: String,
default: 'click',
},
// 多选个数限制selectNum
multipleSelectNum: {
type: Number,
default: 1,
},
// 省市县乡镇,显示层级,默认为2,到区县。0为省,1为市,2为区县,3为乡镇
level: {
type: Number,
default: 2,
},
})
let options: any = ref([]) //树
const watchArr = ref([])
onMounted(() => {
// 获取全量数据
getAllData()
})
//重新定义一个值来接受prop
const isMultiple = ref(false)
//因为prop中的值非动态响应,所以需要通过watch监听,immediate 初始化时接收父组件中的传值
watch(() => props.multipleSelectNum, () => {
// isMultiple.value = props.multipleSelectNum;
if(props.multipleSelectNum > 1) {
isMultiple.value = true
}
console.log(isMultiple.value,props.multipleSelectNum,'---props.multipleSelectNum;');
}, {
immediate: true
})
onBeforeUnmount(() => {})
const emit = defineEmits(['update:modelValue', 'change'])
const handleChange = (e: any, e2: any) => {
watchArr.value = e
emit('change', e)
emit('update:modelValue', e)
}
async function getAllData() {
let res = await api.SearchAdministrativeDivisions({
queryArea: props.designation,
level: props.level
})
options.value = res.data
}
function onFocus(e: any) { }
async function onBeforeFilter(e: any) {
let res = await api.SearchAdministrativeDivisions({
queryArea: e
})
const fn = (arr: any[]) => {
arr.forEach((item, index) => {
if (item.children && item.children.length) {
item.children = fn(item.children)
} else {
if (item.children) delete item.children
}
})
return arr
}
// console.log(options, '---options');
options.value = fn(res.data)
}
// const isMultiple = ref(false)
const innerProps: CascaderProps = {
checkStrictly: props.checkStrictly,
// lazy: true,
value: 'areaCode',
label: 'name',
multiple: isMultiple.value, //modify
expandTrigger: props.expandTrigger,
}
const handleClose = () => { }
const onBlur = () => {
// console.log('---onBlur');
}
const onVisibleChange = (e: any) => {
// if (props.modelValue.length < props.multipleSelectNum && props.multiple == true) {
if (props.modelValue.length < props.multipleSelectNum && isMultiple.value == true) { //modify
function onRabbit(list: any) {
list.forEach((el: any) => {
if (el.children && el.children.length > 0) {
el.children = onRabbit(el.children);
}
el.disabled = false;
el.isFlag = false
});
return list;
}
const newList = onRabbit(options.value);
options.value = newList;
}
}
// 监听
watch(
() => watchArr.value,
(newVal, oldVal) => {
// if (props.multiple == true) {
if (isMultiple.value == true) { //modify
// console.log(oldVal,`watch监听变化前的数`)
// console.log(newVal, `watch监听变化后的数据`)
if (newVal.length >= props.multipleSelectNum) {
function onRabbit(list: any) {
list.forEach((el: any) => {
if (el.children && el.children.length > 0) {
el.children = onRabbit(el.children);
}
newVal.forEach((v: any) => {
if (v[v.length - 1] != el.areaCode) {
if (el.isFlag) {
} else {
el.disabled = true
el.isFlag = true
}
} else {
el.disabled = false
el.isFlag = true
}
})
});
return list;
}
const newList = onRabbit(options.value);
options.value = newList;
} else {
function onRabbit(list: any) {
list.forEach((el: any) => {
if (el.children && el.children.length > 0) {
el.children = onRabbit(el.children);
}
el.disabled = false;
el.isFlag = false
});
return list;
}
const newList = onRabbit(options.value);
options.value = newList;
}
}
},
{
immediate: true, // 立即执行
deep: true // 深度监听
}
)
</script>
<style></style>