蓝桥web模拟题:菜单树检索

本文介绍如何使用Vue和axios实现一个菜单树检索功能,包括数据获取、页面数据遍历、菜单搜索及高亮处理。

菜单树检索

题干

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

具体要求如下:

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

1、若该菜单有父级菜单,则返回其父级菜单及同胞菜单。

2、若该菜单有子级菜单,则返回该菜单及其下子级菜单。

3、若该菜单既无父级也无子级,则返回菜单本身即可。

4、推荐测试字段:查询、首页、管理、配置、维护。

5、 页面加载后显示整个菜单数据。

6、 搜索关键字后显示对应搜索数据,且将关键字高亮显示。

最终效果如【effect.gif】所示

请添加图片描述

提供的文件目录结构:

├── data.json
├── index.html
└── js
├── axios.min.js
├── index.js
└── vue.js

问题解析

依鄙人所见,本题主要有4个点:1. 数据获取,2.页面数据遍历, 3.菜单搜索功能,4. 高亮处理。

获取的数据存放需要一个变量,使用rawData,输入框需要一个变量获取他的值search,搜索的结果同样需要一个变量,当然这个结果是随search变化的,因此我们把它加在computed中,

大致结构如下:

const app = new Vue({
  el: "#app",
  // 在此处补全代码,实现二级菜单搜索功能
  data:{
    search:'',
    rawData:[]
  },
  methods:{
  },
  mounted(){
  },
  computed:{
      menu(){
        return this.rawData
      }
  }
});

解题

1. 数据获取

使用axios直接异步获取文件即可,需要注意的是,获取的时机。可在created创建完vue实例或者mounted挂在完成等事件后获取。比较简单,如下

  mounted(){
    axios.get('./data.json').then(res=>{
        // 获取数据
        this.rawData =  res.data
    })
  },

2.页面数据遍历

其中,v-model监听用户输入,:style="{backgroundColor:item.style}",这里的item.style是最后一步做高亮时,添加的一个类属性,存放背景颜色的值。

注:页面上需要显示哪些内容就要去看datajson文件的格了,这里不多说明

注::key="children.meta.title"要用一个唯一的值,否则会报错

<div id="app">
      <input type="text" v-model="search" placeholder="请输入要搜索的菜单内容" />
      <ul>
        <li v-for="item in menu" :key="item.meta.title">
          <span :style="{backgroundColor: item.style}">{{item.meta.title}}</span>
          <ul v-if="item.children">
            <li v-for="children in item.children" :key="children.meta.title">
              <span :style="{backgroundColor: children.style}">{{children.meta.title}}</span>
            </li>
          </ul>
        </li>
      </ul>
    </div>

3. *菜单搜索功能

  1. 如果为空,显示全部,且都不高亮。这里搜索的结果是如果标题或者找到子项标题存在关键字,就返回整个项,因此,定义一个flag判断要不要添加到结果,如果在每次判断中直接添加可能会出现重复项或者代码复杂难读。

  2. 遍历使用forEach,因为forEachcontinue,因此需要一个if区间来处理遍历子项目

  3. 判断是否包含关键字,可以使用String.includes()方法,包含的话会返回true,否则false。关键字为空返回true。

computed:{
      menu(){
        let result=[]
        this.rawData.forEach(item => {
          let flag = false;
          if(item.meta.title.includes(this.search)){
            flag = true
          }
          if(item.children){
            item.children.forEach((children,index)=>{
              if(children.meta.title.includes(this.search)){
                   flag = true
              }
            })
          }
          flag && result.push(item)
        });
        return result
      }
  }

这时候已经可以搜索了

4. 高亮处理

高亮处理。添加一个属性来存放背景颜色。我们使用style

  • 遍历到项的时候,给style默认为空,css中backgorud值为空的话就没用背景颜色。有关键字就改为黄色

  • 子项目也一样,先给默认值,如果存在关键字,子项的style属性改为黄色

  • 如果关键字为空。那么背景颜色也要为空,因为默认是不加背景的

修改如下:

computed:{
      menu(){
        let result=[]
        this.rawData.forEach(item => {
          let flag = false;
          item.style=''
          if(item.meta.title.includes(this.search)){
            flag = true
            /* 如果为空的话也不高亮,为空是显示全部 */
            this.search && (item.style='yellow')
          }
          if(item.children){
            item.children.forEach((children,index)=>{
              item.children[index].style=''
              if(children.meta.title.includes(this.search)){
                flag = true
                this.search && (item.children[index].style='yellow')
              }
            })
          }
          flag && result.push(item)
        });
        return result
      }
  }

两个关键文件的代码:

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" v-model="search" placeholder="请输入要搜索的菜单内容" />
      <ul>
        <li v-for="item in menu" :key="item.meta.title">
          <span :style="{backgroundColor: item.style}">{{item.meta.title}}</span>
          <ul v-if="item.children">
            <li v-for="children in item.children" :key="children.meta.title">
              <span :style="{backgroundColor: children.style}">{{children.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:{
    search:'',
    rawData:[]
  },
  mounted(){
    axios.get('./data.json').then(res=>{
        // 获取数据
        this.rawData =  res.data
    })
  },
  computed:{
      menu(){
        let result=[]
        this.rawData.forEach(item => {
          let flag = false;
          item.style=''
          if(item.meta.title.includes(this.search)){
            flag = true
            /* 如果为空的话也不高亮,为空是显示全部 */
            this.search && (item.style='yellow')
          }
          if(item.children){
            item.children.forEach((children,index)=>{
              item.children[index].style=''
              if(children.meta.title.includes(this.search)){
                flag = true
                this.search && (item.children[index].style='yellow')
              }
            })
          }
          flag && result.push(item)
        });
        return result
      }
  }
});

文件下载:分为两个文件,一个原题,一个是写完的参考答案。一块打包

资源下载连接

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jayLog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值