【悲战蓝桥杯国赛】【功能实现】菜单树检索

【功能实现】菜单树检索

背景介绍

实际工作中很多前端攻城狮都会遇到这样一个需求:在多级菜单树中模糊搜索匹配的菜单项,并显示出来。

本题需要在已提供的基础项目中使用 Vue.js 知识,实现对已提供的二级菜单树的动态渲染及模糊搜索功能,最终将符合搜索要求的二级菜单树显示在页面中。

步骤准备

在开始答题前,你需要在线上环境终端中键入以下命令,下载并解压所提供的文件。

wget https://labfile.oss.aliyuncs.com/courses/7835/exam11-imi.zip && unzip exam11-imi.zip && rm exam11-imi.zip

下载完成之后的目录结构如下:

├── 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 服务】,就可以在浏览器中看到如下效果:

图片[1]曙光博客-随笔小窝【悲战蓝桥杯国赛】【功能实现】菜单树检索曙光博客-随笔小窝曙光博客

当前显示仅有静态布局,并未实现二级菜单数据的异步获取与显示以及模糊搜索功能。

考试要求

请在 index.js 和 index.html 文件中根据现有 DOM 结构(基础项目提供的 DOM 结构和 id、选择器不要做修改)实现二级菜单数据异步获取(使用 axios)和搜索功能(使用 Vue 2.x 语法)。

具体需求如下:

页面加载后输入框内容为空,页面显示异步获取二级菜单的所有数据;输入待查找的字段后,页面中显示包含该字段的所有菜单数据,并将包含该搜索内容的菜单数据标记为黄色背景,具体表现如下:

  1. 若该菜单有父级菜单,则返回其父级菜单及同胞菜单。
  2. 若该菜单有子级菜单,则返回该菜单及其下子级菜单。
  3. 若该菜单既无父级也无子级,则返回菜单本身即可。
  4. 推荐测试字段:查询、首页、管理、配置、维护。

最终实现效果如下:

图片[2]曙光博客-随笔小窝【悲战蓝桥杯国赛】【功能实现】菜单树检索曙光博客-随笔小窝曙光博客

要求规定

  • 请严格按照考试步骤操作,切勿修改考试默认提供项目中的文件名称、文件夹路径等。
  • 满足题目需求后,保持 Web 服务处于可以正常访问状态,点击「提交检测」系统会自动判分。
<!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" v-model="search" placeholder="请输入要搜索的菜单内容"/>
			<ul>
				<li v-for="item in dataList">
					<span :style='search!=""&&item.meta.title.includes(search) ? "background-color:yellow" : " "'>{{item.meta.title}}</span>
					<ul>
						<li v-for="i in item.children">
							<span :style='search!="" && i.meta.title.includes(search) ? "background-color:yellow" : " "'>{{i.meta.title}}</span>
						</li>
					</ul>
				</li>
			</ul>
		</div>
	</body>
  <script type="text/javascript" src="./js/index.js"></script>
</html>
const app = new Vue({
  el:"#app",
  // 在此处补全代码,实现二级菜单搜索功能
  data:{
    search:"",
    list:[],
    
  },mounted(){
    axios.get("data.json").then(res=>{
      this.list=res.data
    })
  }
  ,computed:{
    dataList(){
     return this.search ? this.list.filter(item=>{
      return item.meta.title.includes(this.search) || (item.children && item.children.some(i=>i.meta.title.includes(this.search)))
     }) :this.list
    }
  ,methods:{

    }
  }
});

该代码实现了一个基于 Vue.js 的二级菜单搜索功能。以下是代码的详细解释,尤其是 item.children && item.children.some(i => i.meta.title.includes(this.search)) 部分:

代码解释

  1. 初始化 Vue 实例
   const app = new Vue({
     el: "#app",
     data: {
       search: "",
       list: [],
     },
     mounted() {
       axios.get("data.json").then(res => {
         this.list = res.data;
       });
     },
     computed: {
       dataList() {
         return this.search ? this.list.filter(item => {
           return item.meta.title.includes(this.search) || (item.children && item.children.some(i => i.meta.title.includes(this.search)));
         }) : this.list;
       }
     },
     methods: {

     }
   });
  1. 数据绑定
  • search: 用于存储用户输入的搜索关键字。
  • list: 用于存储从 data.json 文件中获取的数据。
  1. 生命周期钩子 mounted
  • mounted 钩子在 Vue 实例挂载到 DOM 上之后调用。
  • 使用 axios.get 请求 data.json 文件,并将返回的数据赋值给 list
  1. 计算属性 dataList
  • dataList 是一个计算属性,根据 search 的值动态过滤 list 中的数据。
  • 如果 search 有值,则使用 filter 方法过滤 list 中的项: this.list.filter(item => { return item.meta.title.includes(this.search) || (item.children && item.children.some(i => i.meta.title.includes(this.search))); })

关键部分解释

item.children && item.children.some(i => i.meta.title.includes(this.search))

这一部分用于检查当前项 item 是否有子项,并且至少有一个子项的 meta.title 包含搜索关键字 this.search

  • item.children && ...: 首先检查 item 是否有 children 属性,并且该属性不为空。
  • item.children.some(i => i.meta.title.includes(this.search)): 如果 itemchildren 属性,使用 some 方法遍历 children 数组,检查数组中是否至少有一个子项 i 满足条件 i.meta.title.includes(this.search)。也就是说,子项的 meta.title 中包含搜索关键字 this.search

总结

  • 如果 search 为空,则 dataList 返回整个 list
  • 如果 search 不为空,则 dataList 返回过滤后的 list,其中的每一项 item 必须满足以下任一条件:
  1. item.meta.title 包含 search 关键字。
  2. itemchildren 且至少有一个子项的 meta.title 包含 search 关键字。

这个实现确保了搜索功能可以在一级菜单项和二级菜单项的标题中进行匹配,从而实现二级菜单搜索功能。

© 版权声明
THE END
喜欢就支持一下吧
点赞13赞赏 分享
评论 抢沙发

    暂无评论内容