Files
xzlz_GjWeb/src/components/MyComponents/FrameWork/index.vue
2025-06-08 22:44:18 +08:00

199 lines
4.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="form-item-box zk-frameWork-wrap" :style="{ width: width }">
<el-select
:model-value="frameWork"
:placeholder="placeholder"
@clear="handleClear"
@change="selectChange"
:clearable="clearable"
v-bind="$attrs"
:multiple="multiple"
popper-class="frameWork-select"
>
<el-option value="1" style="display: none"></el-option>
<el-input
v-if="filterable"
v-model="filterText"
style="width: 96% !important; margin: 0 2%; font-size: 12px"
:prefix-icon="Search"
/>
<div class="alllist">
<el-tree
ref="tree"
:data="treeData"
:props="defaultConf"
default-expand-all
:filter-node-method="filterNode"
:show-checkbox="multiple"
:node-key="nodeKey"
@check-change="handleCheckChange"
@node-click="clickNode"
/>
</div>
</el-select>
<!-- <el-icon class="errorIcon"><circle-close-filled /></el-icon>
<el-icon class="checkIcon"><circle-check-filled /></el-icon> -->
</div>
</template>
<script setup>
import { COMPONENT_WIDTH } from '@/constant';
import { nextTick, ref, watch } from "vue";
import { Search } from "@element-plus/icons-vue";
const emits = defineEmits(["handleChange"]); //子组件向父组件事件传递
const props = defineProps({
clearable: {
default: false,
type: Boolean
},
multiple: {
default: false,
type: Boolean
},
filterable: {
default: false,
type: Boolean
},
treeData: {
default: () => [],
type: Array
},
placeholder: {
default: "选择组织机构",
type: String
},
defaultConf: {
type: Object,
default: () => ({
children: "children",
label: "label"
})
},
frameWork: {
type: [String, Array],
default: ""
},
width: {
default: COMPONENT_WIDTH,
type: String
}
});
const nodeKey = "id";
const filterText = ref("");
const mineStatusValue = ref([]); //选中状态存贮
nextTick(() => {
if (props.frameWork) {
if (typeof props.frameWork === "string") {
//传过来的默认值类型
if (props.frameWork) {
tree.value.setCheckedKeys([props.frameWork], false);
}
} else {
if (props.frameWork.length > 0) {
tree.value.setCheckedKeys(props.frameWork, false);
}
}
mineStatusValue.value = treeValueFind(props.treeData, props.frameWork);
}
});
const tree = ref(null);
let deferTimer;
watch(filterText, (val) => {
tree.value.filter(val);
});
const filterNode = (value, data) => {
if (!value) return true;
return data[props.defaultConf.label].indexOf(value) !== -1;
};
//多选选中
const handleCheckChange = () => {
const res = tree.value.getCheckedNodes(true, true); // 这里两个true1. 是否只是叶子节点 2. 是否包含半选节点
mineStatusValue.value = res;
clearTimeout(deferTimer);
deferTimer = setTimeout(() => {
emits("handleChange", res);
}, 200);
};
//节点选择
const clickNode = (data, node, obj) => {
if (props.multiple) {
// 多选不执行
const index = mineStatusValue.value.findIndex((d) => d.id === data.id);
if (index > -1) {
tree.value.setChecked(data, false);
} else {
tree.value.setChecked(data, true);
}
return;
}
if (!data.children) {
mineStatusValue.value.push(data.id);
tree.value.setCheckedKeys([data.id], false);
}
};
//select值变化
const selectChange = (e) => {
if (!props.multiple || !props.treeData.length) {
return false;
}
const arrNew = [];
const dataLength = mineStatusValue.value.length;
const eleng = e.length;
for (let i = 0; i < dataLength; i++) {
for (let j = 0; j < eleng; j++) {
if (e[j] === mineStatusValue.value[i][props.defaultConf.label]) {
arrNew.push(mineStatusValue.value[i][nodeKey]);
break;
}
}
}
setTimeout(() => {
tree.value.setCheckedKeys(arrNew, false);
}, 200);
};
//select clear
const handleClear = (e) => {
mineStatusValue.value = [];
tree.value.setCheckedKeys([], false);
};
const treeValueFind = (tree, arr, newArr = []) => {
if (typeof arr === "string") {
tree.forEach((el) => {
if (el[nodeKey] === arr) {
newArr.push(el);
}
if (el[props.defaultConf.children]) {
treeValueFind(el[props.defaultConf.children], arr, newArr);
}
});
} else {
for (let i = arr.length; i >= 0; i--) {
tree.forEach((el) => {
if (el[nodeKey] === arr[i]) {
newArr.push(el);
arr.splice(i, 1);
}
if (el[props.defaultConf.children] && arr.length > 0) {
treeValueFind(el[props.defaultConf.children], arr, newArr);
}
});
}
}
return newArr;
};
</script>
<style lang="scss" scoped>
.optionclass {
height: auto;
padding: 0;
position: relative;
width: 100%;
overflow-y: overflow;
}
.zk-frameWork-wrap {
.el-select {
width: 100%;
}
}
</style>