欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue實現(xiàn)全局菜單搜索框的示例

 更新時間:2023年02月09日 10:00:43   作者:山山而川~xyj  
本文主要介紹了Vue實現(xiàn)全局菜單搜索框的示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

本篇文章分享一下我在實際開發(fā) Vue 項目時遇到的需要 —— 全局菜單搜索。全局菜單搜索本質(zhì)是 router 的使用,該功能已經(jīng)實現(xiàn),接下來分享一下開發(fā)心得。

一、過濾路由

首先需要過濾出符合條件的路由信息,過濾的條件包含兩個:

  • 路由可以顯示出現(xiàn)(hidden: false
  • 路由元信息中包含 title 屬性

代碼展示:

  /**
   * 篩選出可以在側(cè)邊欄顯示的路由
   * @param routes 路由
   * @param basePath 路徑
   * @param prefixTitle 標(biāo)題
   */
  const generateRoutes = (routes, basePath = '/', prefixTitle = []) => {
    let filterRoutes = []

    for (const route of routes) {
      // 如果路由已經(jīng)隱藏,跳過這次
      if (route.hidden) {
        continue
      }

      const data = {
        path: path.resolve(basePath, route.path),
        title: [...prefixTitle],
      }

      // 僅推送有標(biāo)題的路由
      if (route.meta && route.meta.title) {
        data.title = [...data.title, route.meta.title]

        if (route.redirect !== 'noReDirect') {
          filterRoutes.push(data)
        }
      }

      // 循環(huán)子路由
      if (route.children) {
        const childRoutes = generateRoutes(route.children, data.path, data.title)
        if (childRoutes.length >= 1) {
          filterRoutes = [...filterRoutes, ...childRoutes]
        }
      }
    }
    return filterRoutes
  }

注意:如果路由包含子路由,就要遞歸調(diào)用 generateRoutes 方法, 在遞歸結(jié)束之后把符合條件的路由賦值給 filterRoutes,之后將其返回。

二、搜索框展示路由

實現(xiàn)搜索框使用的是 el-select 組件,在剛進(jìn)入頁面時需要在 onMounted 聲明周期中調(diào)用 generateRoutes 方法,將其賦值給變量 searchPool

  onMounted(() => {
    searchPool.value = generateRoutes(JSON.parse(JSON.stringify(authRoute)))
  })

接下來,需要定義 el-select 組件的 遠(yuǎn)程搜索方法change 事件。其中遠(yuǎn)程搜索方法 query 作用是把符合搜索結(jié)果的信息篩選出來賦值給 options,之后通過下拉選項展示這些信息。而 change 事件是當(dāng)選中路由時實現(xiàn)路由的跳轉(zhuǎn)并完成一些變量的初始化。

  // 搜索框的遠(yuǎn)程搜索方法
  const query = (queryVal) => {
    if (queryVal !== '') {
      options.value = fuse.value.search(queryVal)
    } else {
      options.value = []
    }
  }
  
  /**
   * 輸入框填充內(nèi)容觸發(fā)該方法
   * @param val 搜索框中輸入的值
   */
  const change = (val) => {
    if (val) {
      router.push({
        path: val,
      })
    }
    options.value = []
    search.value = ''
    isShowSearch.value = false
  }  

三、雛形出現(xiàn)但有缺陷

經(jīng)過不斷探索,終于實現(xiàn)了一個全局菜單搜索框,但是這時我們會發(fā)現(xiàn)一個 bug

在這里插入圖片描述

這個問題是必須要輸入完整的路由名稱,路由才會在下拉框中展示,也就是說沒有實現(xiàn)模糊查詢功能,接下來針對這一問題進(jìn)行解決。

四、優(yōu)化搜索方式

路由搜索過程中沒有實現(xiàn)模糊搜索的功能,接下來將借助 fusejs 實現(xiàn)這一功能。fuse.js 具體用法請參照 Fuse 官網(wǎng)。
初始化 fuse:

  /**
   * fuse 實現(xiàn)模糊搜索
   * @param list 需要進(jìn)行模糊搜索的集合
   */
  const fuseInit = (list) => {
    fuse.value = new Fuse(list, {
      shouldSort: true,
      threshold: 0.4,
      location: 0,
      distance: 100,
      minMatchCharLength: 1,
      keys: [
        {
          name: 'title',
          weight: 0.7,
        },
        {
          name: 'path',
          weight: 0.3,
        },
      ],
    })
  }

另外,需要不斷監(jiān)聽 searchPool,當(dāng) searchPool 改變時 調(diào)用 fuseInit 方法。

  /**
   * 監(jiān)聽 searchPool
   */
  watch(searchPool, (list) => {
    fuseInit(list)
  })

添加了模糊搜索功能之后,全局菜單搜索框就基本實現(xiàn),接下來看一下展示效果

在這里插入圖片描述

五、完整代碼展示

<template>
  <div class="search">
    <el-tooltip content="菜單搜索" placement="bottom">
      <el-icon style="font-size: 20px"><Search @click="handleSearch" /></el-icon>
    </el-tooltip>
    <el-dialog
      v-model="isShowSearch"
      class="header_dialog"
      width="600px"
      destroy-on-close
      :show-close="false"
    >
      <el-select
        style="width: 100%"
        ref="headerSearchSelect"
        v-model="search"
        :remote-method="query"
        filterable
        default-first-option
        remote
        placeholder="菜單搜索 :支持菜單名稱、路徑"
        class="header_search_select"
        @change="change"
      >
        <el-option
          v-for="item in options"
          :key="item.item.path"
          :value="item.item.path"
          :label="
            item.item && item.item.title && item.item.title.length && item.item.title.join(' > ')
          "
        >
        </el-option>
      </el-select>
    </el-dialog>
  </div>
</template>
<script lang="ts" setup>
  import { onMounted, ref, watch } from 'vue'
  import { useRouter } from 'vue-router'

  import path from 'path-browserify'
  import Fuse from 'fuse.js'

  import authRoute from '@/router/modules/authRoute'

  const router = useRouter()
  const search = ref('')
  const isShowSearch = ref(false)
  const searchPool = ref([])
  const options = ref([])
  const fuse = ref(null)

  /**
   * fuse 實現(xiàn)模糊搜索
   * @param list 需要進(jìn)行模糊搜索的集合
   */
  const fuseInit = (list) => {
    fuse.value = new Fuse(list, {
      shouldSort: true,
      threshold: 0.4,
      location: 0,
      distance: 100,
      minMatchCharLength: 1,
      keys: [
        {
          name: 'title',
          weight: 0.7,
        },
        {
          name: 'path',
          weight: 0.3,
        },
      ],
    })
  }

  /**
   * 監(jiān)聽 searchPool
   */
  watch(searchPool, (list) => {
    fuseInit(list)
  })

  /**
   * 篩選出可以在側(cè)邊欄顯示的路由
   * @param routes 路由
   * @param basePath 路徑
   * @param prefixTitle 標(biāo)題
   */
  const generateRoutes = (routes, basePath = '/', prefixTitle = []) => {
    let filterRoutes = []

    for (const route of routes) {
      // 如果路由已經(jīng)隱藏,跳過這次
      if (route.hidden) {
        continue
      }

      const data = {
        path: path.resolve(basePath, route.path),
        title: [...prefixTitle],
      }

      // 僅推送有標(biāo)題的路由
      if (route.meta && route.meta.title) {
        data.title = [...data.title, route.meta.title]

        if (route.redirect !== 'noReDirect') {
          filterRoutes.push(data)
        }
      }

      // 循環(huán)子路由
      if (route.children) {
        const childRoutes = generateRoutes(route.children, data.path, data.title)
        if (childRoutes.length >= 1) {
          filterRoutes = [...filterRoutes, ...childRoutes]
        }
      }
    }
    return filterRoutes
  }

  /**
   * 控制搜索框的展示
   */
  const handleSearch = () => {
    isShowSearch.value = true
  }

  onMounted(() => {
    searchPool.value = generateRoutes(JSON.parse(JSON.stringify(authRoute)))
  })

  // 搜索框的遠(yuǎn)程搜索方法
  const query = (queryVal) => {
    if (queryVal !== '') {
      options.value = fuse.value.search(queryVal)
    } else {
      options.value = []
    }
  }

  /**
   * 輸入框填充內(nèi)容觸發(fā)該方法
   * @param val 搜索框中輸入的值
   */
  const change = (val) => {
    if (val) {
      router.push({
        path: val,
      })
    }
    options.value = []
    search.value = ''
    isShowSearch.value = false
  }
</script>
<style lang="scss" scoped>
  .search {
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;

    :deep(.el-dialog) {
      .el-dialog__header {
        display: none;
      }
      .el-dialog__body {
        padding: 0;
      }
    }
    .header_search_select {
      height: 50px;
      :deep(.el-input__wrapper) {
        height: 50px;
      }
    }
  }
</style>

結(jié)論

到此這篇關(guān)于Vue實現(xiàn)全局菜單搜索框的示例的文章就介紹到這了,更多相關(guān)Vue 全局菜單搜索框內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue中Element的table多選表格如何實現(xiàn)單選

    Vue中Element的table多選表格如何實現(xiàn)單選

    這篇文章主要介紹了Vue中Element的table多選表格如何實現(xiàn)單選,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • vue中的模態(tài)對話框組件實現(xiàn)過程

    vue中的模態(tài)對話框組件實現(xiàn)過程

    這篇文章主要介紹了vue中的模態(tài)對話框組件實現(xiàn)過程,通過template定義組件,并添加相應(yīng)的對話框樣式,需要的朋友可以參考下
    2018-05-05
  • vue獲取dom元素注意事項

    vue獲取dom元素注意事項

    這篇文章主要介紹了vue獲取dom元素注意事項及vue獲取dom元素的內(nèi)容,需要的朋友可以參考下
    2017-12-12
  • vue-cli3.0 環(huán)境變量與模式配置方法

    vue-cli3.0 環(huán)境變量與模式配置方法

    vue-cli3.0移除了配置文件目錄: config和build文件夾??梢哉f是非常的精簡了,那移除了配置文件目錄后如何自定義配置環(huán)境變量和模式呢?這篇文章主要介紹了vue-cli3.0 環(huán)境變量與模式 ,需要的朋友可以參考下
    2018-11-11
  • Vue實現(xiàn)全局異常處理的幾種方案

    Vue實現(xiàn)全局異常處理的幾種方案

    本文主要介紹了使用pyscript在網(wǎng)頁中撰寫Python程式的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • el-menu彈出菜單樣式不生效的問題及解決方法

    el-menu彈出菜單樣式不生效的問題及解決方法

    這篇文章主要介紹了el-menu彈出菜單樣式不生效的問題及解決方法,修改彈出框元素不在 el-menu 樣式中,我們需要在 el-menu–popup 中修改樣式,具體操作代碼跟隨小編一起看看吧
    2024-07-07
  • vue.js高德地圖實現(xiàn)熱點圖代碼實例

    vue.js高德地圖實現(xiàn)熱點圖代碼實例

    這篇文章主要介紹了vue.js高德地圖實現(xiàn)熱點圖,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • vue-cli5搭建vue項目的實現(xiàn)步驟

    vue-cli5搭建vue項目的實現(xiàn)步驟

    本文主要介紹了vue-cli5搭建vue項目的實現(xiàn)步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • vue實現(xiàn)websocket客服聊天功能

    vue實現(xiàn)websocket客服聊天功能

    這篇文章主要為大家詳細(xì)介紹了vue實現(xiàn)websocket客服聊天功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • SpringBoot結(jié)合Vue3實現(xiàn)簡單的前后端交互

    SpringBoot結(jié)合Vue3實現(xiàn)簡單的前后端交互

    本文主要介紹了SpringBoot結(jié)合Vue3實現(xiàn)簡單的前后端交互,結(jié)合實際案例,說明了如何實現(xiàn)前后端數(shù)據(jù)的交互,具有一定的?參考價值,感興趣的可以了解一下
    2023-08-08

最新評論