前言
在前端开发中,平时在填写表单中,可能会遇到需要展示选择树状数据的表单组件。但是在element中,并未提供能够处理树状数据选择的 select 选择框组件。所以就此,小温在开发中遇到类似的问题,封装了elementUi 的 select选择框组件。接下来给大家讲述一下! 希望能给大家一些帮助!
提示:以下是本篇文章正文内容,下面案例仅供参考
一、树状部门数据 下拉框单选
效果图如下:
实现代码:
> 组件代码 ( 父 )
<el-form-item label="单位名称: ">
<SelectTree
style="width: 100%"
ref="selectTreeRef"
:props="defaultProps"
:options="treeData"
:value="valueId"
:clearable="true"
:accordion="true"
@getValue="getValue($event)"
/>
</el-form-item>
// 树状数据中,选定子元素名,展示名,选中值变量名
defaultProps: {
children: "list",
label: "orgName",
value: "orgId",
},
// 树状数据
treeData: [],
// 初始展开
valueId: '',
> 组件代码 ( 子 )
此为 vue文件
<template>
<el-select v-model="valueTitle" placeholder="请选择" :clearable="clearable" @clear="clearHandle">
<el-option :value="valueTitle" :label="valueTitle" class="options">
<el-tree
id="tree-option"
ref="selectTree"
:accordion="accordion"
:data="options"
:props="props"
:node-key="props.value"
:default-expanded-keys="defaultExpandedKey"
@node-click="handleNodeClick">
</el-tree>
</el-option>
</el-select>
</template>
<script>
export default {
name: "el-tree-select",
props:{
// 配置项
props:{
type: Object,
default: () => {
return {
value:'id', // ID字段名
label: 'title', // 显示名称
children: 'children' // 子级字段名
};
}
},
// 选项列表数据(树形结构的对象数组)
options:{ type: Array, default: () => { return [] } },
// 初始值
value:{ type: String, default: () => { return null } },
// 可清空选项
clearable:{ type:Boolean, default: () => { return true } },
// 自动收起
accordion:{ type:Boolean, default: () => { return false } }
},
data() {
return {
valueId: null,
valueTitle:'',
defaultExpandedKey:[]
}
},
mounted(){
this.valueId = this.value, // 初始值
this.initHandle()
},
methods: {
// 初始化值
initHandle(){
if(this.valueId){
setTimeout(() => {
window.console.log(this.options)
this.valueTitle = this.$refs.selectTree.getNode(Number(this.valueId)).data[this.props.label] // 初始化显示
this.$refs.selectTree.setCurrentKey(Number(this.valueId)) // 设置默认选中
this.defaultExpandedKey = [this.valueId] // 设置默认展开
}, 500);
} else {
this.valueTitle = ""
}
this.initScroll()
},
// 初始化滚动条
initScroll(){
this.$nextTick(()=>{
let scrollWrap = document.querySelectorAll('.el-scrollbar .el-select-dropdown__wrap')[0]
let scrollBar = document.querySelectorAll('.el-scrollbar .el-scrollbar__bar')
scrollWrap.style.cssText = 'margin: 0px; max-height: none; overflow: hidden;'
scrollBar.forEach(ele => ele.style.width = 0)
})
},
// 切换选项
handleNodeClick(node, obj){
window.console.log(obj);
// if(obj.level <= 1 ) return false
this.valueTitle = node[this.props.label]
this.valueId = node[this.props.value]
this.$emit('getValue', [this.valueId,this.valueTitle])
this.defaultExpandedKey = []
},
// 清除选中
clearHandle(){
this.valueTitle = ''
this.valueId = null
this.defaultExpandedKey = []
this.clearSelected()
this.$emit('getValue', [this.valueId,this.valueTitle])
},
// 清空选中样式
clearSelected(){
let allNode = document.querySelectorAll('#tree-option .el-tree-node')
allNode.forEach((element)=>element.classList.remove('is-current'))
}
},
watch: {
value(){
this.valueId = this.value
this.initHandle()
}
},
}
</script>
<style scoped>
.el-scrollbar .el-scrollbar__view .el-select-dropdown__item{
height: auto;
max-height: 274px;
padding: 0;
overflow: hidden;
overflow-y: auto;
}
.el-select-dropdown__item.selected{
font-weight: normal;
}
ul li >>>.el-tree .el-tree-node__content{
height:auto;
padding: 0 20px;
}
.el-tree-node__label{
font-weight: normal;
}
.el-tree >>>.is-current .el-tree-node__label{
color: #409EFF;
font-weight: 700;
}
.el-tree >>>.is-current .el-tree-node__children .el-tree-node__label{
color:#606266;
font-weight: normal;
}
</style>
二、树状部门数据 下拉框单选
效果图如下:
解释:多选和单选的代码差不多,就不做庸余的复制粘贴了。
- 需要注意的就是,在父组件中,初始值 valueId 为一个数组,因为可多选的原因,返回方法接受的值也为一个数组。
- 在赋值给 elementUi 的 select组件时,也需要将 所选内容进行处理。具体不同的,下面贴一下代码!
<template>
<el-select :value="valueTitle" :clearable="clearable" @clear="clearHandle">
<el-option :value="valueTitle" :label="valueTitle" class="options">
<el-tree
id="tree-option"
ref="selectTree"
:accordion="accordion"
:data="options"
:props="props"
:node-key="props.value"
:default-expanded-keys="defaultExpandedKey"
:filter-node-method="filterNode"
@node-click="handleNodeClick"
>
</el-tree>
</el-option>
</el-select>
</template>
<script>
export default {
name: "el-tree-select",
props: {
/* 配置项 */
props: {
type: Object,
default: () => {
return {
value: "id", // ID字段名
label: "title", // 显示名称
children: "children", // 子级字段名
};
},
},
/* 选项列表数据(树形结构的对象数组) */
options: {
type: Array,
default: () => {
return [];
},
},
/* 初始值 */
value: {
type: Array,
default: () => {
return [];
},
},
/* 可清空选项 */
clearable: {
type: Boolean,
default: () => {
return true;
},
},
/* 自动收起 */
accordion: {
type: Boolean,
default: () => {
return false;
},
},
},
data() {
return {
filterText: "",
valueId: '', // 初始值
valueTitle: "",
defaultExpandedKey: [],
selectData:[]
};
},
mounted() {
this.initHandle();
},
methods: {
// 初始化值
initHandle() {
// window.console.log(this.$refs.selectTree)
if (Array.isArray(this.value) && this.value.length !== 0) {
// window.console.log(this.$refs.selectTree.getNode(10036), '***')
this.value.forEach(item => {
this.valueTitle += `${item[this.props.label]},`
});
this.selectData = JSON.parse(JSON.stringify(this.value));
// this.$refs.selectTree.setCurrentKey(this.valueId); // 设置默认选中
this.defaultExpandedKey = [...(this.value.map(item => item[this.props.value]))]; // 设置默认展开
}
this.initScroll();
},
// 初始化滚动条
initScroll() {
this.$nextTick(() => {
let scrollWrap = document.querySelectorAll(
".el-scrollbar .el-select-dropdown__wrap"
)[0];
let scrollBar = document.querySelectorAll(
".el-scrollbar .el-scrollbar__bar"
);
scrollWrap.style.cssText =
"margin: 0px; max-height: none; overflow: hidden;";
scrollBar.forEach((ele) => (ele.style.width = 0));
});
},
// 切换选项
handleNodeClick(node) {
// window.console.log(node)
if (Array.isArray(node[this.props.children]) && node[this.props.children].length !== 0) {
return;
} else {
let val ='';
// window.console.log(node)
if (!this.selectData.some( item => {
return item[this.props.value] == node[this.props.value]
})) {
this.selectData.push(node)
this.selectData.forEach(el=> val += `${el[this.props.label]},`);
this.valueTitle = val;
this.valueId = node[this.props.value];
this.$emit("getValue", this.selectData);
this.defaultExpandedKey = [];
}
}
},
// 清除选中
clearHandle() {
this.valueTitle = "";
this.valueId = "";
this.defaultExpandedKey = [];
this.selectData = []
this.clearSelected();
this.$emit("getValue", null);
},
/* 清空选中样式 */
clearSelected() {
let allNode = document.querySelectorAll("#tree-option .el-tree-node");
allNode.forEach((element) => element.classList.remove("is-current"));
},
filterNode(value, data) {
if (!value) return true;
return data.name.indexOf(value) !== -1;
},
},
watch: {
value() {
// this.valueId = this.value;
this.initHandle();
},
filterText(val) {
this.$refs.selectTree.filter(val);
},
// options(val) {
// window.console.log(val)
// }
},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.el-scrollbar .el-scrollbar__view .el-select-dropdown__item {
height: auto;
max-height: 274px;
padding: 0;
overflow: hidden;
overflow-y: auto;
}
.el-select-dropdown__item.selected {
font-weight: normal;
}
ul li >>> .el-tree .el-tree-node__content {
height: auto;
padding: 0 20px;
}
.el-tree-node__label {
font-weight: normal;
}
.el-tree >>> .is-current .el-tree-node__label {
color: #409eff;
font-weight: 700;
}
.el-tree >>> .is-current .el-tree-node__children .el-tree-node__label {
color: #606266;
font-weight: normal;
}
.selectInput {
padding: 0 5px;
box-sizing: border-box;
}
/* 开发禁用 */
/* .el-tree-node:focus>.el-tree-node__content{
background-color:transparent;
background-color: #f5f7fa;
color: #c0c4cc;
cursor: not-allowed;
}
.el-tree-node__content:hover{
background-color: #f5f7fa;
} */
</style>
总结
大致内容就到这里结束啦,如果觉得有帮助的话! 希望不要吝啬手中的赞! 给小温点点赞!点个关注吧!