样板图:
HTML结构:
<template>
<div class='common-business-components'>
// 设置底层透明背景层,覆盖整个页面,点击时收回tree
<div class='mask' v-show='maskCommon' @click='closeCommon'></div>
<div id='app' :class="{'on': isVisibleFirstCom}">
<div class='select-box' @click='showFirstLayerCom'>
<div class='curr' :class="{'on': isVisibleFirstCom}">
<Icon type='ios-folder-outline'></Icon>
<span>常用业务</span>
</div>
<div class='list-box clearfix' v-if='isVisibleFirstCom'>
<div class='list list-height'>
<div class='item' v-for='(item, index) in listCom' :key='item.lmId' @click='giveValueCurrCom(index)' :class='{"active":index==comm}'>
{{item.lable}}
<Icon type='ios-arrow-forward' v-if='listCom[index].children' style='padding-left: 5px'></Icon>
</div>
<div class='icon'></div>
</div>
<div class='list' v-if='isVisibleSecondCom'>
<Input v-model='secondaryCom' @on-blur='secondarySearchCom' @on-enter='secondarSearchCom' placeholder='请输入' style='width: 150px; margin: 0 10px;' clearable/>
<div class='item' v-for='(_item, _index) in listCom[comm].children' :key='_item.lmId' @click='clickingSecondLayerCom(_index)' :class='{"active":_index==comSec}'>{{_item.lable}}</div>
</div>
</div>
</div>
</div>
</div>
</template>
js逻辑
<script>
export default {
name: 'commonBusinessComponents',
data () {
return {
ListCom: [],
bizCode: [],
comm: -1,
comSec: -1,
firstTimeClick: 0,
isVisibleFirstCom: false, // 一级
isVisibleSecondCom: false, // 二级
maskCommn: false, // 遮罩
secondaryCom: '' // 二级内置搜索框
}
},
watch: {
// 技能组切换需要刷新接口(监听vuex里面数据的变化这个是我项目组的需求)
'$store.state.bizCode' (val) {
this.bizCode = val
setTimeout(() => {
this.loreMapTree()
}, 20)
}
},
mounted () {
this.bizCode = this.$store.state.bizCode // 先拿到vuex里面定义的全局变量bizCode
},
methods: {
// 接口拿到list数据
loreMapTree () {
this.listCom = []
let bizCode = this.bizCode
let belong = 2 // 区分知识管理=1 o r常用业务=2
let url = this.$api.LORE_MAP_TREE + '?belong=' + belong + '&bizCode=' + bizCode;
this.$xhr.get(url, resp => {
if (resp.retCode == 00) {
this.listCom = resp.data.children
} else {
this.$Message.error(resp.retMsg)
}
})
},
// 业务类型
showFirstLayerCom () {
this.maskCommon = true // 遮罩
this.isVisibleFirstCom = true
this.firstTimeClick += 1
},
// 一级弹出层点击事件
giveValueCurrCom (i) {
this.comm = i
this.comSec = -1;
if (this.listCom[i].children) {
this.isVisibleSecondCom = true
} else {
this.isVisibleSecondCom = false
// 没有二级菜单的也需要点击跳转到详情页面
this.$utils.openView('/commonBusiness', this.listCom[i].lable, this.listCom[i], `business-${this.listCom[i].lable}`)
}
},
// 二级点击事件
clickingSecondLayerCom (index) {
this.isVisibleFirstCom = false
this.isVisibleSecondCom = false
this.comSec = index
event.stopPropagation();
let _item = this.listCom[this.comm].children[this.comSec]
this.$utils.openView('/commonBusiness', _item.lable, _item, `business-${_item.lable}`)
},
// input失焦事件
secondarSearchCom () {
let _list = this.listCom[this.comm].children
for (let i=0; i<_list.length; i++) {
if (_list[i].name === this.secondaryCom) {
this.comSec = i
let _name = this.listCom[this.comm].children[i]
this.$utils.openView('/commonBusiness', _name.lable, _name, `business-${_name}`)
this.closeCommon()
}
}
},
closeCommon () {
this.isVisibleFirstCom = false
this.isVisibleSecondCom = false
this.maskCommon = false
this.secondaryCom = ''
}
}
}
<script>
css样式:
<style lang='less' scoped>
.common-business-components {
.mask {
position: fixed;
height: 50rem;
width: 76rem;
top: 0;
right: 0;
z-index: 11
}
a {
text-emphasis: none;
}
.clearfix:before {
content: '';
display: table;
}
.clearfix:after {
content: '';
display: block;
height: 0;
clear: both;
visibility: hidden;
}
input {
outline: none;
}
ol,
ul {
list-style: none;
}
.select-box {
position: relative;
}
.select-box .curr {
cuesor: pointer;
width: 90px;
font-size: 16px;
position:relative;
right: 220px;
z-index: 10;
background-color: white;
}
.select-box .curr:hover {
border-color: #aaa;
cursor: pointer
}
.on .arraw {
transform: rotate(45deg)
}
.list-box {
margin-top: 10px;
position: absolute;
left: -220px;
border: 1px solid #ddd;
box-shadow: 0px 0px 8px 0px #ccc;
padding: 5px 0;
z-index: 12;
transform: 200ms;
}
.list-box .list {
float: left;
height: 204px;
overflow: auto;
border-left: 1px solid #ccc;
background-color: white;
}
.list-box .list.first {
border: none;
}
.list .item{
height: 38px;
line-height: 38px;
padding: 0 10px;
font-size: 14px;
cursor: pointer;
position: relative;
&:hover{
background-color: rgb(245, 247, 250)
}
}
.list .item.active{
color: #409eff;
font-weight: bold;
}
.list .icon{
position: absolute;
top: 6px;
left: 30px;
width: 10px;
border-left: 1px soid #ddd;
border-top: 1px soid #ddd;
z-index: 20;
transform: rotate(45deg);
background-color: white;
}
.list .arrow-icon{
position: absolute;
top: 17px;
right: 10px;
display: block;
width: 10px;
height: 10px;
border-left: 1px soid #aaa;
border-top: 1px soid #aaa;
transform: rotate(135deg);
transform-origin: 2px 2px;
transition: 200ms;
}
}
</style>