vue+element實(shí)現(xiàn)下拉菜單并帶本地搜索功能示例詳解
需求:
后臺(tái)返回?cái)?shù)組對(duì)像,前端組合成數(shù)組,根據(jù)name組合成一個(gè)個(gè)數(shù)組并把后臺(tái)返回的值當(dāng)成一個(gè)children推入數(shù)組,在數(shù)組中自定義屬性備份數(shù)據(jù)防止搜索的時(shí)候改變?cè)瓟?shù)組使得數(shù)組無法回退


這里是用的vuex存儲(chǔ),因?yàn)槎鄠€(gè)頁面使用同一個(gè)接口;所以沒必要重復(fù)請(qǐng)請(qǐng)求
src\store\module\metadata.js
/*
* @Author: your name
* @Date: 2021-09-02 15:46:45
* @LastEditTime: 2021-09-16 17:39:53
* @LastEditors: Please set LastEditors
* @Description: 控制臺(tái)-數(shù)據(jù)接入-懸浮菜單
* @FilePath: \vue-ui\src\store\module\metadata.js
*/
/**
* 數(shù)據(jù)資源管理懸浮菜單數(shù)據(jù)
*/
import { Loading, Message } from 'element-ui'
import { apiManager } from '@/plugins/ajax'
let loadingInstance
const state = {
allList: [],
navList: [],
name: {}
}
const mutations = {
SET_NAVLIST: (state, list) => {
// 使用深拷貝,防止頁面搜索時(shí)報(bào)錯(cuò)
state.navList = list.map(item => {
if (item.children) {
item.backList = JSON.stringify(item.children)
}
})
},
SET_ALLLIST: (state, list) => {
state.allList = list
},
SET_NAME: (state, obj) => {
Object.assign(state.name, obj)
}
}
const actions = {
requestMetadata({ commit, state }, { name, navList }) {
return new Promise(resolve => {
const nameKey = Object.keys(state.name)
if (nameKey.indexOf(name) !== -1) {
//阻止重復(fù)請(qǐng)求
resolve(state.name[name])
} else {
loadingInstance = Loading.service()
state.name[name] = name
apiManager
.post('/metadata/tableInfo/query')
.then(res => {
commit('SET_ALLLIST', res.data)
for (const i in res.data) {
const item = navList.find(v => v.name === i) //把傳入的name和請(qǐng)回來的key(name)匹配放入
if (item) {
item.children = res.data[i] //把請(qǐng)求回來的每個(gè)對(duì)象下的數(shù)組放入對(duì)應(yīng)的Item.children中
item.navSearch = ''
item.backList = [] //建立備份,在搜索的時(shí)候防止改變?cè)瓟?shù)組
}
}
commit('SET_NAVLIST', navList)
commit('SET_NAME', { [name]: navList })
resolve(navList)
loadingInstance.close()
})
.catch(err => {
resolve([])
loadingInstance.close()
Message.error(err)
})
}
})
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
頁面父組件使用子組件
src\views\console\dataAccessManage\dataResourceTable\FileXs.vue
<transition name="component-fade" mode="out-in"> <floating-menu v-show="isCollapse" :newList='navList' @getDatails='getDatails' /> </transition>
data() {
return {
navList: [
{
imgSrc: require('./../../../../../public/images/m6.png'),
name: 'ftp',
typeName: 'FTP服務(wù)器',
children: [],
total: 0
},
{
imgSrc: require('./../../../../../public/images/m5.png'),
name: 'txt',
typeName: '文件服務(wù)器',
children: [],
total: 0
}
],
},
async mounted() {
const param = {
name: 'fileXs',
navList: this.navList
}
// 請(qǐng)求vuex
this.navlist = await this.$store.dispatch('metadata/requestMetadata', param)
},
子組件
src\views\console\dataAccessManage\components\floatingMenu.vue
<!--
* @Author: your name
* @Date: 2021-09-02 14:01:58
* @LastEditTime: 2021-09-16 17:43:10
* @LastEditors: Please set LastEditors
* @Description: 數(shù)據(jù)資源表中懸浮菜單
* @FilePath: \vue-ui\src\views\console\dataAccessManage\components\floatingMenu.vue
-->
<template>
<div class="data-sheet-main__nav" v-if="sjktcList.length || newList.length">
<div>
<div class="nav__item" v-for="(item,index) in sjktcList" :key="'info2-' + index">
<div class="item_name sjk_name" :class="{ sjk_active: sjkActive == index }" @click="sjktcShow(item.type,index)">{{item.typeName}}</div>
</div>
</div>
<!-- file -->
<el-collapse class="nav__item" v-model="activeNames">
<el-collapse-item class="item_name" :title="item.typeName" :name="item.typeName" v-for="(item,index) in newList" :key="index">
<ul class="nav__item__list">
<li class="list__li">
<el-input v-input-val-bg v-model="item.navSearch" @input="handleNavSearch(item)" prefix-icon="el-icon-search" size="mini" placeholder="請(qǐng)輸入關(guān)鍵字" clearable></el-input>
</li>
<li v-for="(key,i) in item.children" :key="i" :class="{ 'list__li--active': key.id == dbId }" class="list__li" @click="getDatails(key,item)">
<span :title="key.name" class="list--title">{{key.name}}</span>
<span class="list--count">{{key.total || 0}}</span>
</li>
<li class="no-data" v-if="!item.children.length">暫無數(shù)據(jù)</li>
</ul>
</el-collapse-item>
</el-collapse>
</div>
</template>
<script>
import { debounce } from '@/utils'
export default {
name: 'floatingMenu',
props: {
sjktcList: {
type: Array,
default: () => []
},
newList: {
type: Array,
default: () => []
}
},
components: {},
data() {
return {
sjkActive: 0,
navSearch: '',
navChildData: [],
dbId: '',
activeNames: []
}
},
mounted() {
},
methods: {
// 點(diǎn)擊列表中的內(nèi)容
getDatails(args, db) {
this.dbId = args.id
this.$emit('getDatails', { args, db })
},
// eslint-disable-next-line space-before-function-paren
handleNavSearch: debounce(function (obj) {
this.$forceUpdate()//防止input框賦值失敗
const currlist = JSON.parse(obj.backList)
if (obj.navSearch == '') {
obj.children = currlist
} else {
obj.children = currlist.filter(item => {
return item.name.toLowerCase().indexOf(obj.navSearch.toLowerCase()) != -1
})
}
}, 100),
sjktcShow(type, i) {
this.sjkActive = i
this.$emit('sjktcShow', [type])
}
},
watch: {
newList: {
deep: true,
handler(list) {
if (list) {
// 默認(rèn)激活顯示展開list下的0個(gè)菜單
for (let i = 0; i < list.length; i++) {
const item = list[i]
if (!this.dbId && item.children.length) {
this.activeNames = item.typeName
this.getDatails(item.children[0], item)//默認(rèn)請(qǐng)求第一條數(shù)據(jù)內(nèi)容
}
}
}
}
}
}
}
</script>
<style lang='scss' scoped>
.data-sheet-main__nav {
width: 180px;
position: absolute;
top: 0px;
left: -190px;
z-index: 100;
background: #fff;
border: 1px solid #6579fe;
padding-top: 10px;
.sjk_active {
color: $theme !important;
}
.nav__item {
position: relative;
margin-bottom: 15px;
.item_name {
width: 100%;
display: inline-block;
padding-left: 17px;
font-size: 14px;
line-height: 24px;
color: rgba(0, 0, 0, 0.85);
/deep/.el-collapse-item__header {
font-weight: bold;
border-bottom: none;
position: relative;
padding-left: 15px;
.el-collapse-item__arrow {
position: absolute;
left: 0;
transform: rotate(270deg);
}
.el-collapse-item__arrow.is-active {
transform: rotate(90deg);
}
}
&:hover {
cursor: pointer;
}
}
.no-data {
text-align: center;
color: #999;
padding: 10px 0;
width: 100%;
}
img {
width: 100%;
height: 50px;
}
.nav__item--total {
position: absolute;
display: block;
width: 30px;
height: 30px;
background: #fff;
border: 1px solid #ccc;
border-radius: 50%;
line-height: 30px;
border: 1px solid #71b1ec;
box-shadow: 0 3px 6px #156d90;
text-align: center;
color: #fd0b0b;
font-size: 16px; /*no*/
top: 0;
right: 0;
transform: translate(25%, -20%);
}
.nav__item__list {
display: flex;
max-height: 246px;
overflow-y: auto;
flex-wrap: wrap;
.list__li {
width: 100%;
margin-top: 5px;
line-height: 30px;
padding: 0 6px 0 17px;
position: relative;
cursor: pointer;
color: #333;
&:hover {
color: $blue;
}
.list--title {
width: 90px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
float: left;
&:hover {
color: #409eff;
}
}
.list--count {
color: #46a0fc;
float: right;
}
}
.list__li--active {
color: $blue;
}
}
}
/deep/.el-collapse {
border-top: none;
}
}
.data-sheet-main__list {
flex: 1;
margin-left: 20px;
.list-header {
flex-direction: column;
.order {
text-align: right;
a {
background: #6579fe;
font-family: PingFangSC-Regular;
font-size: 12px;
line-height: 22px;
color: #ffffff;
padding: 6px;
border-radius: 4px;
}
}
}
.handler--fixed-right {
padding: 25px 10px;
}
.nodata {
text-align: center;
font-size: 16px;
}
}
</style>
到此這篇關(guān)于vue+element實(shí)現(xiàn)下拉菜單并帶本地搜索功能的文章就介紹到這了,更多相關(guān)vue element下拉菜單搜索內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
在Vue中用canvas實(shí)現(xiàn)二維碼和圖片合成海報(bào)的方法
這篇文章主要介紹了在Vue中用canvas實(shí)現(xiàn)二維碼和圖片合成海報(bào)的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06
vxe-table中vxe-grid(高級(jí)表格)的使用方法舉例
vxe-table是一個(gè)基于vue的表格組件,下面這篇文章主要給大家介紹了關(guān)于vxe-table中vxe-grid(高級(jí)表格)的使用方法,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-05-05
動(dòng)態(tài)加載權(quán)限管理模塊中的Vue組件
本篇文章給大家詳細(xì)講解了如何在權(quán)限管理模塊中動(dòng)態(tài)的加載VUE組件的過程,有這方面需求的朋友跟著學(xué)習(xí)下吧。2018-01-01
vue移動(dòng)端裁剪圖片結(jié)合插件Cropper的使用實(shí)例代碼
本篇文章主要介紹了vue移動(dòng)端裁剪圖片結(jié)合插件Cropper的使用實(shí)例代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07
vue form表單使用resetFields函數(shù)出現(xiàn)的問題
這篇文章主要介紹了vue form表單使用resetFields函數(shù)出現(xiàn)的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05

