jmalcloud-view/src/components/VContextmenu/file-contextmenu.vue
2025-06-20 15:48:33 +08:00

143 lines
3.4 KiB
Vue

<template>
<v-contextmenu ref="contextShow" class="file-contextmenu" :class="className" @show="show" @hide="hide" @contextmenu="contextmenu">
<div v-for="item of menus" :key="item.label">
<!-- 一级菜单 -->
<v-contextmenu-item v-if="!item.child" :divider="!!item.divider" @click="menusOperations(item.operation, $event)"
class="menuitem home-contextmenu">
<svg-icon v-if="item.iconClass" :icon-class="item.iconClass"></svg-icon>
<div class="home-contextmenu-title">
<span class="menuitem text">{{ item.label }}</span>
<span v-if="item.shortcut">
<kbd v-for="key in item.shortcut" :style="{fontSize: key === '⌘' ? '14px' : '12px'}">{{ key }}</kbd>
</span>
</div>
</v-contextmenu-item>
<v-contextmenu-submenu class="home-contextmenu" v-else :icon-class="item.iconClass" :title="item.label">
<!-- 二级菜单 -->
<div v-for="itemSecond of item.child" :key="itemSecond.operation">
<v-contextmenu-item
v-if="!itemSecond.child"
:divider="!!itemSecond.divider"
@click="menusOperations(itemSecond.operation, $event)"
>
<svg-icon
v-if="itemSecond.iconClass"
:icon-class="itemSecond.iconClass"
></svg-icon>
{{ itemSecond.label }}
</v-contextmenu-item>
<v-contextmenu-submenu
v-if="itemSecond.child"
:icon-class="itemSecond.iconClass"
:title="itemSecond.label"
>
</v-contextmenu-submenu>
</div>
</v-contextmenu-submenu>
</div>
</v-contextmenu>
</template>
<script>
export default {
name: 'file-contextmenu',
props: {
menus: {
type: Array,
default: () => []
},
className: {
type: String,
default: ''
}
},
data() {
return {
}
},
methods: {
menusOperations() {
this.$emit('menusOperations', ...arguments)
},
showMenu(e) {
this.$refs.contextShow.show(e)
},
hideMenu(e) {
this.$refs.contextShow.hide(e)
},
show() {
this.$emit('show')
},
hide() {
this.$emit('hide')
},
contextmenu() {
this.$emit('contextmenu')
}
}
}
</script>
<style scoped lang="scss">
@import "~@/styles/variables.scss";
>>> .v-contextmenu.v-contextmenu-sub {
border-radius: $dialogBorderRadius;
padding: 8px;
}
.file-contextmenu.v-contextmenu {
min-width: 180px;
border-radius: $dialogBorderRadius;
padding: 8px;
background-color: rgba(255, 255, 255, .75);
-webkit-backdrop-filter: blur(16px) saturate(180%);
backdrop-filter: blur(16px) saturate(180%);
.v-contextmenu-divider {
margin: 5px 0;
}
li {
cursor: pointer;
padding: 0;
font-size: 16px;
min-width: 136px;
line-height: 35px;
&:hover {
border-radius: 10px;
background-color: #409eff30;
color: #000;
}
}
li > .text {
font-weight: normal;
}
li > .svg-icon {
font-size: 20px;
cursor: pointer;
}
.v-contextmenu-item {
padding: 0 10px;
display: flex;
align-items: center;
justify-content: space-between;
>>> .svg-icon {
margin-right: 10px;
font-size: 20px;
}
}
>>> .home-contextmenu-title {
width: 100%;
display: flex;
justify-content: space-between;
}
}
</style>