124
This commit is contained in:
117
src/components/contextmenu/index.vue
Normal file
117
src/components/contextmenu/index.vue
Normal file
@ -0,0 +1,117 @@
|
||||
<template>
|
||||
<transition name="el-zoom-in-center">
|
||||
<div
|
||||
class="el-popper is-pure is-light el-dropdown__popper ba-contextmenu"
|
||||
:style="`top: ${state.axis.y + 18}px;left: ${ state.axis.x - 14 }px;width:150px`"
|
||||
:key="Math.random()"
|
||||
v-show="state.show"
|
||||
aria-hidden="false"
|
||||
data-popper-placement="bottom"
|
||||
>
|
||||
<ul class="el-dropdown-menu">
|
||||
<template v-for="(item, idx) in props.items" :key="idx">
|
||||
<li
|
||||
class="el-dropdown-menu__item"
|
||||
:class="item.disabled ? 'is-disabled' : ''"
|
||||
tabindex="-1"
|
||||
@click="onContextmenuItem(item)"
|
||||
>
|
||||
<Icon size="12" :name="item.icon" />
|
||||
<span>{{ item.label }}</span>
|
||||
</li>
|
||||
</template>
|
||||
</ul>
|
||||
<span
|
||||
class="el-popper__arrow"
|
||||
:style="{ left: `${state.arrowAxis}px` }"
|
||||
></span>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
onMounted,
|
||||
onUnmounted,
|
||||
reactive,
|
||||
toRaw,
|
||||
defineProps,
|
||||
defineEmits
|
||||
} from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { useStore } from "vuex";
|
||||
const route = useRoute();
|
||||
|
||||
const props = defineProps({
|
||||
items: {
|
||||
type: Array,
|
||||
default: []
|
||||
}
|
||||
});
|
||||
const emits = defineEmits(["contextmenuItemClick"]);
|
||||
const state = reactive({
|
||||
show: false,
|
||||
axis: {
|
||||
x: 0,
|
||||
y: 0
|
||||
},
|
||||
menu: {},
|
||||
arrowAxis: 10
|
||||
});
|
||||
|
||||
const onShowContextmenu = (menu, axis) => {
|
||||
state.menu = menu;
|
||||
state.axis = axis;
|
||||
state.show = true;
|
||||
};
|
||||
|
||||
const onContextmenuItem = (item) => {
|
||||
if (item.disabled) return;
|
||||
item.menu = toRaw(state.menu);
|
||||
emits("contextmenuItemClick", item);
|
||||
};
|
||||
|
||||
const onHideContextmenu = () => {
|
||||
state.show = false;
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
onShowContextmenu,
|
||||
onHideContextmenu
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
document.body.addEventListener("click", onHideContextmenu);
|
||||
});
|
||||
onUnmounted(() => {
|
||||
document.body.removeEventListener("click", onHideContextmenu);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.ba-contextmenu {
|
||||
z-index: 9999;
|
||||
position: fixed;
|
||||
}
|
||||
.el-popper,
|
||||
.el-popper.is-light .el-popper__arrow::before {
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
border: none;
|
||||
}
|
||||
.el-dropdown-menu__item {
|
||||
padding: 8px 20px;
|
||||
user-select: none;
|
||||
}
|
||||
.el-dropdown-menu__item .icon {
|
||||
margin-right: 5px;
|
||||
}
|
||||
.el-dropdown-menu__item:not(.is-disabled) {
|
||||
&:hover {
|
||||
background-color: var(--el-dropdown-menuItem-hover-fill);
|
||||
color: var(--el-dropdown-menuItem-hover-color);
|
||||
.fa {
|
||||
color: var(--el-dropdown-menuItem-hover-color) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user