在vue3中实现一个IM消息右键菜单

1.封装一个右键菜单

<template>
  <teleport to="body">
    <div v-if="contextMenuVisible" class="right-click-menu" :style="{ top: `${top}px`, left: `${left}px` }">
      <ul v-for="(item, index) in menuList" :key="index">
        <li @click="handleItemClick(item)">{{ item }}</li>
      </ul>
    </div>
  </teleport>
</template>

<script setup lang='ts'>
//props接收参数
//top,left接收右键菜单的弹出坐标
//handleItemClick父组件传入一个方法,实现子组件向父组件传递点击的是哪个菜单
//contextMenuVisible控制这个右键菜单是否显示
//menuList传入一个菜单列表
defineProps(['top', 'left', 'handleItemClick', 'contextMenuVisible',  'menuList'])
</script>

<style scoped lang='scss'>
.right-click-menu {
  position: fixed;
  background-color: #fff;
  box-shadow: 0 15px 30px rgba(0, 0, 0, .3);
  z-index: 1000;
  border-radius: 10px;
  width: 118px;
  font-size: 14px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

ul {
  list-style-type: none;
  padding: 0;
  margin: 0;
  text-indent: 18px;
  // background-color: red;
  display: flex;
  justify-content: center;
  align-items: center;
}

li {
  // padding: 8px;
  width: 110px;
  height: 40px;
  cursor: pointer;
  border-radius: 10px;
  display: flex;
  align-items: center;

}

li:hover {
  background-color: #F3F4F6;
}
</style>

2.引入组件使用

<template>
   <div v-for="item in friendMessage" :key="item.id">
     <div class="mes">
   		<span class="mesSpan" @contextmenu="showContextMenu($event, item)">{{ item.chatContent }}</span>
     </div>
   </div>
   <div class="rightClick">
     	<RightClickMenu v-if="contextMenuVisible" :top="contextMenuTop" :left="contextMenuLeft" :handleItemClick="handleContextMenuItemClick" :visible="contextMenuVisible" :menuList="menuList" />
   </div>
</template>
<script setup lang="ts">
import {ref} from 'vue'
import RightClickMenu from "@/components/RightClickMenu/index.vue";

let menuList = ref(['复制', '转发', '收藏', '多选', '撤回', '删除']);
const targetElement = ref(null);
const contextMenuVisible = ref(false);
const contextMenuTop = ref(0);
const contextMenuLeft = ref(0);
//显示右键菜单的函数,在右键点击时调用。
//它阻止了默认的右键菜单并设置了菜单的位置,同时添加了一个点击事件监听器来在其他地方点击时隐藏菜单。
const showContextMenu = (event, item) => {
  //阻止默认右键事件
  event.preventDefault();
  //菜单可见
  contextMenuVisible.value = true;
  //获取鼠标坐标
  contextMenuTop.value = event.clientY;
  contextMenuLeft.value = event.clientX;
  // 检测是否超出浏览器视口区域  一个菜单40px*6个
  const menuHeight = 240; // 右键菜单的高度
  const windowHeight = window.innerHeight;

  if (event.clientY + menuHeight > windowHeight) {
    // 如果右键菜单超出视口底部,调整位置为向上弹出
    contextMenuTop.value -= menuHeight;
  }
  window.addEventListener("click", hideContextMenu);
};
//隐藏右键菜单的函数,移除点击事件监听器,并将 contextMenuVisible 设置为 false
const hideContextMenu = () => {
  contextMenuVisible.value = false;
  window.removeEventListener("click", hideContextMenu);
};
//处理右键菜单项点击的函数,你可以在这里处理点击菜单项后的逻辑。
const handleContextMenuItemClick = (item) => {
  console.log(`Clicked on ${item}`);
  hideContextMenu();
};
<script>

3.效果

在这里插入图片描述

  • 11
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要在Vue3使用AntV X6实现右键菜单功能,你可以按照以下步骤操作: 1. 安装依赖:在Vue项目安装AntV X6和ant-design-vue库。 ``` npm install @antv/x6 ant-design-vue --save ``` 2. 创建右键菜单组件:创建一个Vue组件,作为X6图形编辑器右键菜单的容器。 ```vue <template> <a-dropdown :trigger="['contextmenu']" @visible-change="onVisibleChange"> <a-menu slot="overlay" :style="{ width: '120px' }"> <a-menu-item @click="deleteNode">删除节点</a-menu-item> </a-menu> <div class="x6-contextmenu" ref="container"></div> </a-dropdown> </template> <script> import { defineComponent } from 'vue'; import { Dropdown, Menu, message } from 'ant-design-vue'; export default defineComponent({ name: 'X6ContextMenu', components: { Dropdown, Menu, MenuItem: Menu.Item, }, emits: ['deleteNode'], mounted() { this.menu = this.$refs.container; this.menu.addEventListener('contextmenu', (e) => { e.preventDefault(); e.stopPropagation(); }); }, methods: { onVisibleChange(visible) { if (visible) { this.$emit('contextmenu', this.menu); } }, deleteNode() { this.$emit('deleteNode'); }, }, }); </script> ``` 3. 在X6图形编辑器添加右键菜单:在X6图形编辑器添加右键菜单功能。 ```vue <template> <div class="x6-editor"> <x6-contextmenu @contextmenu="onContextMenu" @deleteNode="deleteNode"></x6-contextmenu> <div class="x6-graph" ref="container"></div> </div> </template> <script> import { defineComponent } from 'vue'; import { Graph, Node } from '@antv/x6'; import X6ContextMenu from './X6ContextMenu.vue'; export default defineComponent({ name: 'X6Editor', components: { X6ContextMenu, }, data() { return { graph: null, }; }, mounted() { this.graph = new Graph({ container: this.$refs.container, grid: true, // 其他配置 }); // 添加节点 const node = this.graph.addNode({ // 节点配置 }); // 右键菜单事件 this.graph.on('contextmenu', ({ x, y }) => { this.$refs.contextmenu.show(x, y); }); }, methods: { onContextMenu(menu) { // 清空菜单 menu.innerHTML = ''; // 添加菜单项 const deleteMenuItem = document.createElement('a-menu-item'); deleteMenuItem.innerHTML = '删除节点'; deleteMenuItem.addEventListener('click', () => { this.deleteNode(); }); menu.appendChild(deleteMenuItem); }, deleteNode() { // 删除节点 this.graph.removeNode(node); }, }, }); </script> ``` 这样就可以在Vue3使用AntV X6实现右键菜单功能了。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值