【功能实现】菜单树检索
背景介绍 实际工作中很多前端攻城狮都会遇到这样一个需求:在多级菜单树中模糊搜索匹配的菜单项,并显示出来。
本题需要在已提供的基础项目中使用 Vue.js 知识,实现对已提供的二级菜单树的动态渲染及模糊搜索功能,最终将符合搜索要求的二级菜单树显示在页面中。
步骤准备 在开始答题前,你需要在线上环境终端中键入以下命令,下载并解压所提供的文件。
wget https://labfile.oss.aliyuncs.com/courses/7835/exam11-imi.zip && unzip exam11-imi.zip && rm exam11-imi.zip copy 下载完成之后的目录结构如下:
├── data.json # 二级菜单总数据
├── index.html # 页面布局
└── js
├── axios.min.js # 用于异步获取数据的 Ajax 封装库
├── index.js # 页面功能实现的逻辑代码
└── vue.js # 版本为 2.x 的 Vue.js 框架
源码下载后,选中 index.html 右键启动 Web Server 服务(Open with Live Server),让项目运行起来。
接着,打开环境右侧的【Web 服务】,就可以在浏览器中看到如下效果:
当前显示仅有静态布局,并未实现二级菜单数据的异步获取与显示以及模糊搜索功能。
考试要求 请在 index.js 和 index.html 文件中根据现有 DOM 结构(基础项目提供的 DOM 结构和 id、选择器等不要做修改)实现二级菜单数据异步获取(使用 axios)和搜索功能(使用 Vue 2.x 语法)。
具体需求如下:
页面加载后输入框内容为空,页面显示异步获取二级菜单的所有数据;输入待查找的字段后,页面中显示包含该字段的所有菜单数据,并将包含该搜索内容的菜单数据标记为黄色背景,具体表现如下:
若该菜单有父级菜单,则返回其父级菜单及同胞菜单。 若该菜单有子级菜单,则返回该菜单及其下子级菜单。 若该菜单既无父级也无子级,则返回菜单本身即可。 推荐测试字段:查询、首页、管理、配置、维护。 最终实现效果如下:
要求规定 请严格按照考试步骤操作,切勿修改考试默认提供项目中的文件名称、文件夹路径等。 满足题目需求后,保持 Web 服务处于可以正常访问状态,点击「提交检测」系统会自动判分。 总通过次数: 105 | 总提交次数: 125 | 通过率: 84%
难度: 简单 标签: Web 前端
题解
二层循环遍历菜单项,将匹配到字段的菜单项添加到数组中即可。注意每次input值发生改变时,需要遍历的数据要重新获取。
index.html
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>test</title>
<script src="./js/vue.js"></script>
<script src="./js/axios.min.js"></script>
<style>
input{
width: 200px;
height: 32px;
padding-left:5px;
}
</style>
</head>
<body>
<!-- 需求:输入待查找的字段,输出包含该字段的所有菜单数据。
1、若该菜单有父级菜单,则返回其父级菜单及同胞菜单。
2、若该菜单有子级菜单,则返回该菜单及其下子级菜单。
3、若该菜单既无父级也无子级,则返回菜单本身即可。
测试字段:查询、首页、管理、配置、维护 -->
<div id="app">
<input type="text" placeholder="请输入要搜索的菜单内容"/>
<ul>
<li v-for="item in list" :key="item">
<!-- 三目判断是否有背景色标记 --->
<span :style="item.meta.bgc? 'background-color:yellow' : ''">{{ item.meta.title }}</span>
<ul>
<li v-for="item2 in item.children">
<span :style="item2.meta.bgc? 'background-color:yellow' : ''">{{ item2.meta.title }}</span>
</li>
</ul>
</li>
</ul>
</div>
</body>
<script type="text/javascript" src="./js/index.js"></script>
</html>
index.js
const app = new Vue({
el:"#app",
data: {
list: [],
temp: [],
value: ""
},
mounted() {
this.initData()
},
methods: {
initData() {
axios.get("./data.json").then((res) => {
this.list = res.data
this.temp = res.data
})
}
},
watch: {
value() {
let t = this.temp
if(this.value === "") {
this.list = this.temp
}
let arr = []
t.forEach(item => {
let flag = false
if (item.meta.title.includes(this.value)) {
flag = true
arr.push(item)
item.meta.bgc = true
}
if (item.children) {
item.children.forEach(item2 => {
if (item2.meta.title.includes(this.value)) {
item2.meta.bgc = true
if (!flag) {
flag = true
arr.push(item)
}
}
})
}
}
)
this.list = arr
}
}
});
|