197 lines
4.0 KiB
Vue
197 lines
4.0 KiB
Vue
<template>
|
|
<el-dialog
|
|
v-model="dialogVisible"
|
|
width="30%"
|
|
class="overlay"
|
|
:show-close="false"
|
|
>
|
|
<template #header>
|
|
<input
|
|
v-model="searchInput"
|
|
class="quick-input"
|
|
placeholder="请输入你需要快捷到达的功能"
|
|
>
|
|
</template>
|
|
|
|
<div
|
|
v-for="(option,index) in options"
|
|
:key="index"
|
|
>
|
|
<div
|
|
v-if="option.children.length"
|
|
class="quick-title"
|
|
>{{ option.label }}</div>
|
|
<div
|
|
v-for="(item,key) in option.children"
|
|
:key="index+'-'+key"
|
|
class="quick-item"
|
|
@click="item.func"
|
|
>
|
|
{{ item.label }}
|
|
</div>
|
|
</div>
|
|
|
|
<template #footer>
|
|
<span class="dialog-footer">
|
|
<el-button @click="close">关闭</el-button>
|
|
</span>
|
|
</template>
|
|
</el-dialog>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { reactive, ref, watch } from 'vue'
|
|
import { useRouter, useRoute } from 'vue-router'
|
|
import { useRouterStore } from '@/pinia/modules/router'
|
|
import { useUserStore } from '@/pinia/modules/user'
|
|
|
|
defineOptions({
|
|
name: 'CommandMenu',
|
|
})
|
|
|
|
const router = useRouter()
|
|
const route = useRouter()
|
|
const userStore = useUserStore()
|
|
const routerStore = useRouterStore()
|
|
const dialogVisible = ref(false)
|
|
const searchInput = ref('')
|
|
const options = reactive([])
|
|
const deepMenus = (menus) => {
|
|
const arr = []
|
|
menus.forEach(menu => {
|
|
if (menu.children && menu.children.length > 0) {
|
|
arr.push(...deepMenus(menu.children))
|
|
} else {
|
|
if (menu.meta.title && menu.meta.title.indexOf(searchInput.value) > -1) {
|
|
arr.push({
|
|
label: menu.meta.title,
|
|
func: () => changeRouter(menu)
|
|
})
|
|
}
|
|
}
|
|
})
|
|
return arr
|
|
}
|
|
|
|
const addQuickMenu = () => {
|
|
const option = {
|
|
label: '跳转',
|
|
children: []
|
|
}
|
|
const menus = deepMenus(routerStore.asyncRouters[0].children)
|
|
option.children.push(...menus)
|
|
options.push(option)
|
|
}
|
|
|
|
const addQuickOption = () => {
|
|
const option = {
|
|
label: '操作',
|
|
children: []
|
|
}
|
|
const quickArr = [
|
|
{
|
|
label: '亮色主题',
|
|
func: () => changeMode('light')
|
|
}, {
|
|
label: '暗色主题',
|
|
func: () => changeMode('dark')
|
|
}, {
|
|
label: '退出登录',
|
|
func: () => userStore.LoginOut()
|
|
}
|
|
]
|
|
option.children.push(...quickArr.filter(item => item.label.indexOf(searchInput.value) > -1))
|
|
options.push(option)
|
|
}
|
|
|
|
addQuickMenu()
|
|
addQuickOption()
|
|
|
|
const open = () => {
|
|
dialogVisible.value = true
|
|
}
|
|
|
|
const changeRouter = (e) => {
|
|
const index = e.name
|
|
const query = {}
|
|
const params = {}
|
|
routerStore.routeMap[index]?.parameters &&
|
|
routerStore.routeMap[index]?.parameters.forEach((item) => {
|
|
if (item.type === 'query') {
|
|
query[item.key] = item.value
|
|
} else {
|
|
params[item.key] = item.value
|
|
}
|
|
})
|
|
if (index === route.name) return
|
|
if (e.name.indexOf('http://') > -1 || e.name.indexOf('https://') > -1) {
|
|
window.open(e.name)
|
|
} else {
|
|
router.push({ name: index, query, params })
|
|
}
|
|
dialogVisible.value = false
|
|
}
|
|
|
|
const changeMode = (e) => {
|
|
if (e === null) {
|
|
userStore.changeSideMode('dark')
|
|
return
|
|
}
|
|
userStore.changeSideMode(e)
|
|
}
|
|
|
|
const close = () => {
|
|
dialogVisible.value = false
|
|
}
|
|
|
|
defineExpose({ open })
|
|
|
|
watch(searchInput, () => {
|
|
options.length = 0
|
|
addQuickMenu()
|
|
addQuickOption()
|
|
})
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
.overlay {
|
|
border-radius: 4px;
|
|
.el-dialog__header{
|
|
padding:0 !important;
|
|
margin-right:0 !important;
|
|
}
|
|
.el-dialog__body{
|
|
padding: 12px !important;
|
|
height: 50vh;
|
|
overflow: auto !important;
|
|
}
|
|
.quick-title{
|
|
margin-top: 8px;
|
|
font-size: 12px;
|
|
font-weight: 600;
|
|
color: #666;
|
|
}
|
|
.quick-input{
|
|
color: #666;
|
|
border-radius: 4px 4px 0 0;
|
|
border:none;
|
|
padding: 12px 16px;
|
|
box-sizing: border-box;
|
|
width: 100%;
|
|
font-size: 16px;
|
|
border-bottom: 1px solid #ddd;
|
|
}
|
|
.quick-item{
|
|
font-size: 14px;
|
|
padding: 8px;
|
|
margin: 4px 0;
|
|
&:hover{
|
|
cursor: pointer;
|
|
background: #eee;
|
|
border-radius: 4px;
|
|
}
|
|
}
|
|
}
|
|
|
|
</style>
|