最终效果如下
dropdown
组件代码如下
<template>
<div>
<div ref="dropT" style="width: fit-content;">
<slot></slot>
<div ref="dropB" v-show="showMenu" :style="dropstyle" class="absolute-div">
<slot name="dropdown"></slot>
</div>
</div>
</div>
</template>
<script setup>
import { onMounted, onUnmounted, ref } from 'vue';
const showMenu = ref(false);
const dropT = ref(null);
const dropB = ref(null);
const dropstyle = ref({
top: '50px', left: '20px'
})
onMounted(() => {
if (dropT.value) {
dropT.value.addEventListener('mouseenter',
function (e) {
const rect = dropT.value.getBoundingClientRect();
showMenu.value = true;
dropstyle.value.top = (rect.bottom).toString() + 'px';
dropstyle.value.left = (e.clientX - 30).toString() + 'px';
document.onmousemove = function (d) {
d.preventDefault();
if (d.clientX < rect.right & d.clientY < rect.bottom) {
const rectB = dropB.value.getBoundingClientRect();
dropstyle.value.top = (rect.bottom).toString() + 'px';
dropstyle.value.left = (d.clientX - (rectB.right - rectB.left) / 2).toString() + 'px';
}
};
}, false);
dropT.value.addEventListener('mouseleave',
function (e) {
showMenu.value = false;
document.onmousemove = null;
}, false);
}
})
onUnmounted(() => {
document.onmousemove = null;
})
</script>
<style>
.absolute-div {
position: fixed;
background-color: #ffffff;
padding: 10px;
z-index: 888;
border: 1px solid #e4e7ed;
border-radius: 4px;
box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.12);
}
.absolute-div::after {
content: "";
position: absolute;
top: -9px;
left: 50%;
margin-left: -5px;
border-width: 5px;
border-style: solid;
border-color: transparent transparent #ffffff transparent;
}
</style>
使用方式如下
<template>
<div class="control">
<Dropdown>
<div style="color:#ffffff">鼠标移入出现下拉,鼠标在标签内移动时下拉菜单跟着鼠标位置移动</div>
<template #dropdown>
<button class="pretty-button">下载</button>
<button class="pretty-button">查看</button>
</template>
</Dropdown>
</div>
</template>
<script setup lang="ts">
import Dropdown from '@/components/dropDown/index.vue';
</script>
<style scoped>
.pretty-button {
background-color: #67c23a;
border: none;
color: white;
padding: 5px 12px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
cursor: pointer;
border-radius: 5px;
transition: all 0.3s;
min-width: 62px;
}
.pretty-button:hover {
background-color: #529b2e;
}
</style>