1.过滤效果:
2. cardList 数据源:
[
{
"id": 4,
"createTime": "2024-03-28 02:47:18",
"updateTime": "2024-03-28 02:47:18",
"uniqueId": "test",
"name": "测试",
"sort": 1,
"deletable": true,
"enable": true,
"modelList": [
{
"uniqueId": "test",
"name": "应",
"icon": "el-icon-question",
"sort": 1,
"enable": true,
"size": 0,
"groupId": 4,
"createTime": "2024-03-28 02:47:37",
"updateTime": "2024-03-28 02:47:37"
}
]
},
{
"id": 2,
"createTime": "2024-03-21 00:45:43",
"updateTime": "2024-03-21 00:45:43",
"uniqueId": "sh_app",
"name": "应用管理",
"sort": 1,
"deletable": true,
"enable": true,
"modelList": [
{
"uniqueId": "server",
"name": "服务器",
"icon": "el-icon-s-management",
"sort": 1,
"enable": true,
"size": 3,
"groupId": 2,
"createTime": "2024-03-21 07:51:01",
"updateTime": "2024-03-27 07:48:48"
},
{
"uniqueId": "app",
"name": "应用",
"icon": "el-icon-s-promotion",
"sort": 1,
"enable": true,
"size": 1,
"groupId": 2,
"createTime": "2024-03-21 00:46:01",
"updateTime": "2024-03-27 07:48:58"
}
]
},
{
"id": 1,
"createTime": "2024-03-20 08:10:34",
"updateTime": "2024-03-20 08:10:34",
"uniqueId": "default",
"name": "未分类",
"sort": 0,
"deletable": false,
"enable": true,
"modelList": [
{
"uniqueId": "sdf",
"name": "应测试",
"icon": "el-icon-s-help",
"sort": 1,
"enable": true,
"size": 0,
"groupId": 1,
"createTime": "2024-03-28 02:40:20",
"updateTime": "2024-03-28 02:40:20"
}
]
}
]
3.vue组件源代码:
<template>
<div class="content">
<div class="subTitle">资源目录</div>
<div class="container">
<el-input
style="margin-left: 10px"
placeholder="请输入关键字"
v-model="searchValue"
class="input-with-select"
>
<el-button
slot="append"
icon="el-icon-search"
@click="filterData"
></el-button>
</el-input>
<div class="cardStyle">
<el-card class="box-card" v-for="(v, i) in cardList" :key="i">
<div slot="header" class="clearfix">
<span class="subName">{{ v.name }}</span>
</div>
<ul>
<li
v-for="(o, e) in v.modelList"
:key="e"
class="text item"
:class="{
active: showIndex == e && currentUniqueId == o.uniqueId,
}"
@click="goToPage(o)"
@mouseenter="
showIndex = e;
currentUniqueId = o.uniqueId;
"
@mouseleave="showIndex = -1"
>
<span
><i style="color: #409eff" :class="o.icon"></i
><span style="margin-left: 10px">{{ o.name }}</span></span
>
<span class="num">{{ o.size }}</span>
</li>
</ul>
</el-card>
</div>
</div>
</div>
</template>
<script>
import { mapActions, mapMutations } from "vuex";
import { findAll } from "@/api/cmdb/model";
export default {
data() {
return {
value: "",
searchValue: "",
options: [],
cardList: [],
showIndex: -1,
currentUniqueId: null,
};
},
watch: {},
mounted() {
this.getList();
},
methods: {
...mapMutations(["setMutCurrentPageTitle", "setActiveModel"]),
goToPage(value) {
this.$router.push({ path: "/resource/template" });
this.setActiveModel(value);
this.setMutCurrentPageTitle(value.name);
},
async getList() {
await findAll({})
.then((res) => {
if (res.code == 0) {
this.cardList = res.data;
} else {
res.desc && this.$message.error(res.desc);
}
})
.catch((err) => {
err.desc && this.$message.error(err.desc);
});
},
// 通过关键字查询过滤嵌套数据
async filterData() {
// 过滤之前先请求拿到最新的嵌套数据 cardList
await this.getList();
const search = this.searchValue.toLowerCase().trim();
if (!search) return this.cardList;
let filterList = this.cardList.map((item) => {
return {
...item,
modelList: item.modelList.filter((o) => {
return o.name.toLowerCase().includes(search);
}),
};
});
// 如果子节点数组没有就删除掉,不展示
filterList.map((v, i) => {
if (v.modelList.length == 0) {
filterList.splice(i, 1);
}
});
// 过滤筛选后赋值,这里会影响原数据cardList,所以过滤之前先请求,拿到最新的cardList
this.cardList = filterList;
},
},
};
</script>
<style scoped lang="scss">
.content {
.contentTop {
margin-bottom: 20px;
span {
display: inline-block;
margin-right: 20px;
}
}
.subTitle {
font-size: 18px;
margin-left: 10px;
}
.container {
padding: 30px 0;
width: 100%;
height: 100%;
// background-color: #f9f9f9;
::v-deep .el-input-group {
line-height: normal;
display: inline-table;
width: 20%;
border-collapse: separate;
border-spacing: 0;
}
.cardStyle {
margin-top: 30px;
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: flex-start;
flex-wrap: wrap;
.box-card {
width: 23%;
margin: 10px;
.subName {
font-size: 16px;
font-weight: 700;
}
li {
width: 100%;
height: 40px;
margin: 5px 0;
padding: 0 10px;
display: flex;
align-items: center;
justify-content: space-between;
cursor: pointer;
.num {
color: #ccc;
}
&.active {
background: #ecf3ff;
}
}
}
}
}
}
</style>