vue纯前端过滤嵌套数据,通过关键字搜索过滤嵌套数据

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>

相关推荐
AvatarGiser5 分钟前
《ElementUI/Plus 踩坑》el-table + sortablejs 拖拽顺序错乱(Vue2/3适用)
前端·vue.js·elementui
louqle7 分钟前
vue2:树形控件el-tree中加载两种不同结构的数据
javascript·vue.js·elementui
蓝染-惣右介26 分钟前
【若依RuoYi-Vue | 项目实战】帝可得后台管理系统(二)
java·前端·后端·vue·springboot
我码玄黄1 小时前
HTML翻牌器:用CSS和HTML元素创造动态数字展示
前端·css·html
-草莓星球杯1 小时前
若依VUE项目安全kind-of postcss vite漏洞扫描和修复
前端·javascript·vue.js
LJ小番茄1 小时前
关于wordPress中的用户登录注册等问题
前端·javascript·css·html·wordpress
小郝同学(恩师白云)2 小时前
SpringMVC后续4
java·服务器·前端
优联前端2 小时前
uni-app-通过vue-cli命令行快速上手
开发语言·前端·vue.js·uni-app·优联前端
点燃银河尽头的篝火(●'◡'●)3 小时前
【BurpSuite】Cross-site scripting (XSS 学徒部分:1-9)
前端·web安全·网络安全·xss
Jiaberrr4 小时前
手把手教你:微信小程序实现语音留言功能
前端·微信小程序·小程序·语音·录音