199 lines
4.9 KiB
Vue
199 lines
4.9 KiB
Vue
|
|
<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); // 这里两个true,1. 是否只是叶子节点 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>
|