vue3 数据可视化大屏 树状图菜单效果整理,二级菜单,可以选择选择菜单并将菜单对应的id传给父组件。
使用
<pageItem title="item4">
<item4 v-model:id="id4" v-model:type="type4"></item4>
</pageItem>
id4: '',
type4: '',
树状图代码
/**
* @Author: 858834013@qq.com
* @Name: item4
* @Date: 2023年07月19日15:59:05
* @Desc:
*/
<template>
<div class="container">
<div class="search">
<input type="text" placeholder="请选择设备">
<img src="./assets/icon_search.png" alt="">
</div>
<div class="tree">
<ul>
<li v-for="node in treeData" :key="node.id">
<div class="titleInfo" @click="toggleExpand(node)">
<div class="zhankai">
<img v-if="node.expanded" src="./assets/icon_zhankai.png" alt="">
<img v-else src="./assets/icon_shousuo.png" alt="">
</div>
<div class="shexiangtou">
<img src="./assets/icon_shebei.png" alt="">
</div>
<span :class="{active:type==node.id}">{{ node.label }}</span>
</div>
<ul v-show="node.expanded">
<li v-for="child in node.children" :key="child.id">
<div class="titleInfo">
<div class="shexiangtou">
<img src="./assets/icon_shebei1.png" alt="">
</div>
<span :class="{active:id==child.id}" @click="getId(node,child)">{{ child.label }}</span>
</div>
</li>
</ul>
</li>
</ul>
</div>
</div>
</template>
<script>
import selected from "./selected.vue";
// import {sensor_statistics} from "@/api/api/user.js";
export default {
name: 'item1s',
components: {selected},
data() {
return {
treeData: [
{
id: 1,
label: '设备列表',
selected: false,
expanded: false,
children: [
{
id: 2,
label: '设备1',
selected: false,
expanded: false,
},
{
id: 3,
label: '设备2',
selected: false,
expanded: false,
}
]
},
{
id: 5,
label: '设备列表2',
selected: false,
expanded: false,
children: [
{
id: 6,
label: '设备1',
selected: false,
expanded: false,
},
{
id: 7,
label: '设备2',
selected: false,
expanded: false
}
]
},
],
};
},
props: {
id: {
type: [Number, String],
default() {
return '';
}
},
type: {
type: [Number, String],
default() {
return '';
}
},
},
mounted() {
// this.sensor_statistics()
},
methods: {
// 请求接口获取数据
sensor_statistics() {
var that = this;
that.treeData = []
sensor_statistics().then(res => {
var data = res.data
data.forEach((type) => {
var data1 = {
id: type.sensorTypeKey,
label: type.sensorTypeVal,
selected: false,
expanded: false,
children: []
}
type.sensorList.forEach((type2) => {
data1.children.push({
id: type2.id,
label: type2.name,
selected: false,
expanded: false,
})
});
that.treeData.push(data1)
});
}).catch(err => {
})
},
toggleExpand(node) {
node.expanded = !node.expanded;
},
getId(data, child) {
this.$emit('update:type', data.id)
this.$emit('update:id', child.id)
}
}
}
</script>
<style lang="scss" scoped>
.container {
width: calc(100% - 40px);
height: calc(100% - 40px);
position: relative;
margin: 0 auto;
.search {
width: 100%;
height: 38px;
background: url("./assets/searchbg.png") no-repeat;
background-size: 100% 100%;
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
input {
background: none;
width: calc(100% - 12px);
outline: none;
border: none;
position: relative;
height: calc(100% - 3px);
color: #fff;
margin-left: 12px;
}
/* 标准写法 */
input::placeholder {
color: rgba(126, 175, 236, 1);
}
/* WebKit 内核浏览器(Chrome、Safari) */
input::-webkit-input-placeholder {
color: rgba(126, 175, 236, 1);
}
/* Internet Explorer 浏览器 */
input:-ms-input-placeholder {
color: rgba(126, 175, 236, 1);
}
img {
width: 16px;
height: 16px;
margin-right: 14px;
flex-shrink: 0;
}
}
}
.tree {
width: 100%;
position: relative;
height: calc(100% - 300px);
ul {
list-style-type: none;
font-size: 14px;
font-family: MiSans;
font-weight: 400;
color: #FFFFFF;
}
}
.titleInfo {
display: flex;
justify-content: flex-start;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
height: 45px;
cursor: pointer;
span.active {
font-weight: bold;
color: rgba(120, 233, 255, 1.00);
}
}
.shexiangtou {
width: 34px;
display: flex;
justify-content: center;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
img {
height: 14px;
}
}
.zhankai {
display: flex;
justify-content: flex-start;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
img {
margin-right: 10px;
}
}
</style>
源文件下载
效果代码 vue3 vite js nodejs 14