|
@@ -1,34 +1,34 @@
|
|
|
<template>
|
|
|
- <div ref="modalRef"
|
|
|
- class="tabs_item 小手指"
|
|
|
- v-if="modal"
|
|
|
- :style="displayLocation">
|
|
|
- <slot v-if="slots"/>
|
|
|
- <ul v-else>
|
|
|
- <li v-for="(item,index) in props.config"
|
|
|
- :style="prohibit(item)"
|
|
|
- @click="handlingClickEvents(item.click, index)">
|
|
|
- <div class="icon">
|
|
|
- <component v-if="item.icon" :is="item.icon"/>
|
|
|
- </div>
|
|
|
- <div class="writtenWords">
|
|
|
- {{ item.name }}
|
|
|
- </div>
|
|
|
- <div class="suffix"/>
|
|
|
- </li>
|
|
|
- <li @click="modal = false">
|
|
|
- <div class="icon">
|
|
|
- <el-icon>
|
|
|
- <Close/>
|
|
|
- </el-icon>
|
|
|
- </div>
|
|
|
- <div class="writtenWords">
|
|
|
- 关闭
|
|
|
- </div>
|
|
|
- <div class="suffix"/>
|
|
|
- </li>
|
|
|
- </ul>
|
|
|
- </div>
|
|
|
+ <div ref="modalRef"
|
|
|
+ class="tabs_item 小手指"
|
|
|
+ v-if="modal"
|
|
|
+ :style="displayLocation">
|
|
|
+ <slot v-if="slots"/>
|
|
|
+ <ul v-else>
|
|
|
+ <li v-for="(item,index) in props.config"
|
|
|
+ :class="prohibit(item)"
|
|
|
+ @click="handlingClickEvents(item.click, index, item)">
|
|
|
+ <div class="icon">
|
|
|
+ <component v-if="item.icon" :is="item.icon"/>
|
|
|
+ </div>
|
|
|
+ <div class="writtenWords">
|
|
|
+ {{ item.name }}
|
|
|
+ </div>
|
|
|
+ <div class="suffix"/>
|
|
|
+ </li>
|
|
|
+ <li @click="modal = false">
|
|
|
+ <div class="icon">
|
|
|
+ <el-icon>
|
|
|
+ <Close/>
|
|
|
+ </el-icon>
|
|
|
+ </div>
|
|
|
+ <div class="writtenWords">
|
|
|
+ 关闭
|
|
|
+ </div>
|
|
|
+ <div class="suffix"/>
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+ </div>
|
|
|
</template>
|
|
|
|
|
|
<script setup name='RightClickMenu'>
|
|
@@ -36,22 +36,22 @@ import {ref} from "vue";
|
|
|
import {onClickOutside} from '@vueuse/core'
|
|
|
|
|
|
const props = defineProps({
|
|
|
- config: {
|
|
|
- type: Array,
|
|
|
- default: [{
|
|
|
- name: '请设置', click: () => {
|
|
|
- console.warn('请先设置')
|
|
|
- }
|
|
|
- }]
|
|
|
- },
|
|
|
- mousePosition: {
|
|
|
- type: Object,
|
|
|
- default: {}
|
|
|
- },
|
|
|
- closeManually: {
|
|
|
- type: Boolean,
|
|
|
- default: false
|
|
|
- }
|
|
|
+ config: {
|
|
|
+ type: Array,
|
|
|
+ default: [{
|
|
|
+ name: '请设置', click: () => {
|
|
|
+ console.warn('请先设置')
|
|
|
+ }
|
|
|
+ }]
|
|
|
+ },
|
|
|
+ mousePosition: {
|
|
|
+ type: Object,
|
|
|
+ default: {}
|
|
|
+ },
|
|
|
+ closeManually: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false
|
|
|
+ }
|
|
|
})
|
|
|
|
|
|
|
|
@@ -59,86 +59,111 @@ const modal = ref(false)
|
|
|
const modalRef = ref(null)
|
|
|
|
|
|
onClickOutside(modalRef, () => {
|
|
|
- if (!props.closeManually) {
|
|
|
- modal.value = false
|
|
|
- }
|
|
|
+ if (!props.closeManually) {
|
|
|
+ modal.value = false
|
|
|
+ }
|
|
|
})
|
|
|
|
|
|
let displayLocation = $ref({
|
|
|
- left: '0px',
|
|
|
- top: '0px'
|
|
|
+ left: '0px',
|
|
|
+ top: '0px'
|
|
|
})
|
|
|
|
|
|
-const handlingClickEvents = (cb, index) => {
|
|
|
- let data = props.config[index]
|
|
|
- if (data.validator && !data.validator(props.mousePosition.data)) {
|
|
|
- modal.value = false
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- cb(props.mousePosition.data, props.mousePosition.index);
|
|
|
+const handlingClickEvents = (cb, index, item) => {
|
|
|
+ if (whetherToDisable(item)) {
|
|
|
+ modal.value = false
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ let data = props.config[index]
|
|
|
+ if (data.validator && !data.validator(props.mousePosition.data)) {
|
|
|
modal.value = false
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ cb(props.mousePosition.data, props.mousePosition.index);
|
|
|
+ modal.value = false
|
|
|
}
|
|
|
|
|
|
const prohibit = (data) => {
|
|
|
+ return whetherToDisable(data) ? 'disable' : ''
|
|
|
+}
|
|
|
+
|
|
|
+const whetherToDisable = (data) => {
|
|
|
+
|
|
|
+ function validator() {
|
|
|
if (!data.validator) {
|
|
|
- return
|
|
|
+ return false
|
|
|
}
|
|
|
if (!data.validator(props.mousePosition.data)) {
|
|
|
- return {
|
|
|
- color: '#c8c9cc',
|
|
|
- cursor: 'not-allowed'
|
|
|
- }
|
|
|
+ return true
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!props.mousePosition.data) {
|
|
|
+ if (data.allowDataNull) {
|
|
|
+ return validator()
|
|
|
+ } else {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return validator()
|
|
|
+
|
|
|
}
|
|
|
|
|
|
watch(() => props.mousePosition, () => {
|
|
|
- modal.value = true
|
|
|
- nextTick(() => {
|
|
|
- calculateTheLocation(props.mousePosition.event.pageX, props.mousePosition.event.pageY)
|
|
|
- })
|
|
|
+ modal.value = true
|
|
|
+ nextTick(() => {
|
|
|
+ calculateTheLocation(props.mousePosition.event.pageX, props.mousePosition.event.pageY)
|
|
|
+ })
|
|
|
})
|
|
|
|
|
|
const calculateTheLocation = (x, y) => {
|
|
|
|
|
|
- const {innerWidth: windowWidth, innerHeight: windowHeight} = window;
|
|
|
+ const {innerWidth: windowWidth, innerHeight: windowHeight} = window;
|
|
|
|
|
|
- const menu = modalRef.value;
|
|
|
- const menuHeight = menu.offsetHeight;
|
|
|
- const menuWidth = menu.offsetWidth
|
|
|
+ const menu = modalRef.value;
|
|
|
+ const menuHeight = menu.offsetHeight;
|
|
|
+ const menuWidth = menu.offsetWidth
|
|
|
|
|
|
|
|
|
- if (menuWidth + x + 20 >= windowWidth) {
|
|
|
- displayLocation.left = x - menuWidth + 'px';
|
|
|
- } else {
|
|
|
- displayLocation.left = x + 'px';
|
|
|
- }
|
|
|
+ if (menuWidth + x + 20 >= windowWidth) {
|
|
|
+ displayLocation.left = x - menuWidth + 'px';
|
|
|
+ } else {
|
|
|
+ displayLocation.left = x + 'px';
|
|
|
+ }
|
|
|
|
|
|
- if (menuHeight + y + 20 >= windowHeight) {
|
|
|
- displayLocation.top = y - menuHeight + 'px'
|
|
|
- } else {
|
|
|
- displayLocation.top = y + 'px';
|
|
|
- }
|
|
|
+ if (menuHeight + y + 20 >= windowHeight) {
|
|
|
+ displayLocation.top = y - menuHeight + 'px'
|
|
|
+ } else {
|
|
|
+ displayLocation.top = y + 'px';
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
const close = () => {
|
|
|
- modal.value = false
|
|
|
+ modal.value = false
|
|
|
}
|
|
|
|
|
|
defineExpose({
|
|
|
- close
|
|
|
+ close
|
|
|
})
|
|
|
|
|
|
let slots = $ref(false)
|
|
|
onMounted(() => {
|
|
|
- if (!!useSlots().default) {
|
|
|
- slots = true
|
|
|
- }
|
|
|
+ if (!!useSlots().default) {
|
|
|
+ slots = true
|
|
|
+ }
|
|
|
})
|
|
|
|
|
|
</script>
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
+
|
|
|
+.disable {
|
|
|
+ color: #c8c9cc;
|
|
|
+ cursor: not-allowed;
|
|
|
+}
|
|
|
+
|
|
|
.tabs_item {
|
|
|
position: fixed;
|
|
|
margin: 5px;
|