vue实现手机端组织结构树
该功能以替换当前数据实现层级切换,如需要跳转页面那没有!!! 如果想实现每次请求接口查询下一级 也没有!!!
最新版本将在npm上更新,不再更新文档
npm安装方式(推荐)
npm i mobile-tree-vue
效果图:
<!--
* @Descripttion: vue实现手机端组织结构树
* @Author: xuyanqi
* @Date: 2022-06-01 15:09:06
-->
<template>
<div class="vue-mobile-tree">
<!-- 导航头 -->
<div class="nav">
<span v-for="(val, index) in navList" :key="index" @click="navHandler(val)">{{ val }}</span>
</div>
<!-- 组织列表 -->
<div class="list">
<div class="row" v-for="(item, index) in data" :key="index" @click="rowHandler(item)">
<div class="img">{{ item.label | imgTextFilter }}</div>
<span class="label">{{ item.label }}</span>
<span class="total" v-if="item['total']">{{ item.total }} {{ unit }}</span>
</div>
</div>
</div>
</template>
<script>
export default {
filters: {
imgTextFilter(val) {
if (val.length > 2) {
return val.substring(0, 2)
}
return val
},
},
props: {
tree: {
type: Array,
default: () => [
{
label: '集团总部',
total: 20,
children: [
{
label: '集团党委',
total: 5,
children: [
{
label: '张三',
children: [],
},
{
label: '李四',
children: [],
},
{
label: '王五',
children: [],
},
],
},
{
label: '集团经理层',
total: 5,
children: [],
},
{
label: '集团纪委',
total: 10,
children: [],
},
],
},
{
label: '第一事业部',
total: 30,
children: [],
},
{
label: '第二事业部',
total: 25,
children: [],
},
{
label: '第三事业部',
total: 36,
children: [],
},
{
label: '第四事业部',
total: 36,
children: [],
},
{
label: '第五事业部',
total: 36,
children: [],
},
{
label: '第六事业部',
total: 36,
children: [],
},
{
label: '第七事业部',
total: 36,
children: [],
},
],
},
unit: {
type: String,
default: '人',
},
},
data() {
return {
navList: ['全部'],
data: this.tree,
currentRow: [],
}
},
methods: {
rowHandler(row) {
// 判断是否是第一次点击则记录当前的一级数据
if (this.navList.length === 1) {
this.currentRow = [row]
}
this.navList.push(row.label)
this.data = row.children
},
navHandler(val) {
if (val === '全部') {
this.data = this.tree
this.navList = ['全部']
} else {
// 处理导航栏
const index = this.navList.indexOf(val)
this.navList.splice(index + 1, this.navList.length)
// 处理展示的组织
this.backHandler(this.currentRow, val)
}
},
backHandler(list, val) {
for (let i = 0; i < list.length; i++) {
if (list[i].label === val) {
this.data = list[i].children
} else {
this.backHandler(list[i].children, val)
}
}
},
},
}
</script>
<style scoped>
.vue-mobile-tree {
font-family: serif;
}
.nav {
font-size: 13px;
color: #a7a7a7;
margin: 20px 10px;
}
.nav > span:not(:first-child)::before {
content: ' > ';
color: #a7a7a7;
}
.nav > span:last-child {
color: #0984e3;
}
.row {
display: flex;
align-items: center;
border-bottom: 1px solid #eeeeee;
padding: 10px;
}
.img {
width: 35px;
height: 35px;
background-color: #0984e3;
line-height: 35px;
text-align: center;
color: #ffffff;
border-radius: 6px;
font-size: 13px;
font-weight: bold;
}
.label {
margin-left: 10px;
color: #505050;
font-size: 14px;
}
.total {
position: absolute;
right: 17px;
font-size: 13px;
color: #858585;
}
</style>