前端自定义下拉菜单dropdown组件

最终效果如下

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>
  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值