vue项目使用组件库是element-ui,涉及到的组件库组件有 Tree 树形控件、Icon 图标
样式如下图
下拉选择框-勾选树形结构数据
具体代码
<template>
<div class="customize-tree" ref="targetBlock">
<div class="floating-box" :style="`bottom: ${chunkHeight}px; display: ${selectGroupShow};`" >
<el-tree
ref="cognitiveGoalsTree"
:data="CognitiveGoalsOptions"
show-checkbox
node-key="value"
@check="handleCheckChange"
:props="defaultProps">
</el-tree>
</div>
<div class="select-data-group" v-if="checkedNodes.length>0" ref="variableHeightBlock" @click="selectDataGroup">
<span v-for="(item,index) in checkedNodes" :key="index" class="item">
<span v-if="item.fName">{{ item.fName + '/' + item.label }}</span>
<span v-else>{{ item.label }}</span>
<i class="el-icon-error" @click.stop="deleteCheckedNode(index)"></i>
</span>
<div class="right-icon right-icon1" :style="`top: ${chunkHeight/2-14}px;`">
<i v-if="selectGroupShow == 'none'" class="el-icon-arrow-down"></i>
<i v-else class="el-icon-arrow-up"></i>
<i class="el-icon-error" @click.stop="deleteCheckedNode(0,'del')"></i>
</div>
</div>
<div class="select-data-group" v-else ref="variableHeightBlock" @click="selectDataGroup">
<span class="placeholder-text">请选择知识点</span>
<div class="right-icon" >
<i v-if="selectGroupShow == 'none'" class="el-icon-arrow-down"></i>
<i v-else class="el-icon-arrow-up"></i>
</div>
</div>
</div>
</template>
js
data(){
return {
CognitiveGoalsOptions: [], // 知识点+认知目标三级列表
CognitiveGoalsValue: [], // 选中的认知目标 三级列表选中项
defaultProps: {
children: 'children',
label: 'label'
},
checkedNodes: [], // 树形结构选中的数据
chunkHeight: 52,// 获取块的高度
selectGroupShow: 'none', // 隐藏
}
}
mounted () {
// 监听点击事件
document.addEventListener('click', this.handleClickOutside);
},
beforeDestroy(){
// 卸载点击事件
document.removeEventListener('click', this.handleClickOutside);
},
methods: {
// 点击事件
selectDataGroup() {
this.selectGroupShow = this.selectGroupShow == 'none' ? 'block' : 'none'
},
handleCheckChange(e, data) {
if (data.checkedNodes && data.checkedNodes.length > 0) {
let arr = []
data.checkedNodes.forEach(ele => {
if (ele.children && ele.children.length>0) {
} else {
arr.push(ele)
this.CognitiveGoalsValue.push(ele.value)
}
});
this.checkedNodes = arr
} else {
this.checkedNodes = []
this.CognitiveGoalsValue = []
}
this.$nextTick(() => {
this.getBlockHeight();
});
},
getBlockHeight() {
if (this.$refs.variableHeightBlock) {
this.chunkHeight = this.$refs.variableHeightBlock.offsetHeight + 12;
}
},
deleteCheckedNode(index,str) {
let arr = []
this.CognitiveGoalsValue = []
if (str == 'del') {
this.checkedNodes = []
} else {
this.checkedNodes.splice(index,1)
this.checkedNodes.forEach(ele => {
arr.push(ele.value)
})
}
this.CognitiveGoalsValue = arr
this.$refs.cognitiveGoalsTree.setCheckedKeys(arr);
this.$nextTick(() => {
this.getBlockHeight();
});
},
handleClickOutside(event) {
const targetBlock = this.$refs.targetBlock;
if (!targetBlock.contains(event.target)) {
this.selectGroupShow = 'none'
}
},
}
css
.customize-tree{
position: relative;
.select-data-group{
width: 430px;
padding: 4px 0;
min-height: 38px;
border: 1px solid #DCDFE6;
border-radius: 4px;
display: flex;
flex-wrap: wrap;
position: relative;
&:hover{
border-color: #c0c4cc;
}
.placeholder-text{
height: 30px;
line-height: 30px;
display: inline-block;
font-size: 14px;
color: #c0c4cc;
padding-left: 14px;
}
.right-icon{
color: #c0c4cc;
position: absolute;
right: 8px;
top: 10px;
}
.right-icon1{
.el-icon-error{
display: none;
}
&:hover{
.el-icon-arrow-down{
display: none;
}
.el-icon-arrow-up{
display: none;
}
.el-icon-error{
display: inline-block;
}
}
}
.item{
max-width: calc(100% - 35px);
display: inline-block;
background-color: #f4f4f5;
border-color: #e9e9eb;
border-radius: 4px;
color: #909399;
margin: 2px 0 2px 6px;
display: flex;
flex-wrap: wrap;
align-items: center;
padding: 0 8px;
line-height: 22px;
span{
display: inline-block;
max-width: calc(100% - 20px);
font-size: 12px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
overflow: hidden;
}
i{
font-size: 14px;
margin-left: 6px;
color: #C0C4CC;
cursor: pointer;
&:hover{
color: #909399;
}
}
}
}
.floating-box{
padding: 6px 20px 6px 10px;
border: 1px solid #E4E7ED;
border-radius: 4px;
background-color: #FFF;
box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
z-index: 2001;
max-height: 800px;
max-width: 1000px;
overflow-y: auto;
overflow-x: auto;
position: absolute;
}
}