DeepSeek+Vue:打造丝滑的右键菜单(RightClickMenu)

在构建现代Web应用时,用户体验(UX)的设计和优化至关重要。右键菜单(RightClickMenu)作为一种常见的交互模式,能够为用户提供快捷的操作选项,极大提升操作的便利性和效率。Vue.js,作为一款轻量级且高效的前端框架,以其独特的响应式数据绑定和组件化开发特性,成为了开发者们打造优质用户体验的首选工具。而DeepSeek,作为一个集成AI编程功能的平台,能够为Vue开发者提供智能化的代码生成和优化建议,进一步加速开发进程。本文将深入探讨如何结合DeepSeek与Vue.js,共同打造一款体验丝滑、功能丰富的右键菜单组件,旨在为用户带来更加流畅和高效的交互体验。

📚前言

博时基金在人工智能应用方面一直保持前沿探索。2024 年初,公司发现了 DeepSeek 模型在自动编写代码和逻辑推理方面的潜力,率先在自有的昇腾服务器上部署了 DeepSeek-V1 模型,作为公司智能开发工具的基座模型,并在 2024 年 8 月升级为 DeepSeek-V2 模型。2025 年,随着 DeepSeek-R1 模型的发布,博时基金迅速完成内部部署,并开始探索它在投资研究、咨询服务和软件开发等方面的应用。R1 模型在推理能力上表现优异,可以帮助提升工作效率,支持业务创新,同时,它对算力的需求也有所降低,为进一步推广应用创造了条件 。

📚页面效果

图片[1]-DeepSeek+Vue:打造丝滑的右键菜单(RightClickMenu)-趣考网

📚指令输入

已经创建好了一个基于Vue3的组合式API的项目(Composition API),并能正常运行起来,请帮我用 Vue3的组合式API(Composition API) 生成一个 右键菜单(RightClickMenu) 的功能组件,所有代码都保存在components/RightClickMenu 下的文件夹中。功能组件的script标签中只有setup属性,使用普通 JavaScript 实现,不使用TypeScript。

功能要有,如下属性:

以下是制作 Vue3 右键菜单组件的方案:

属性 (Props)

  1. 菜单项配置

  • items: Array (必填)

    MenuItem={id:string|number,//唯一标识label:string,//显示文本icon?:string,//可选图标disabled?:boolean,//禁用状态divider?:boolean,//是否为分隔线children?:MenuItem[],//子菜单handler?:Function//自定义点击处理}
  1. 定位控制

  • position: { x: number, y: number } (必填,通过右键事件坐标初始化)

  • autoAdjust: boolean (自动调整位置防止超出屏幕边界)

  1. 样式控制

  • theme: \’light\’ | \’dark\’ (预设主题样式)

  • customClass: string (自定义 CSS 类)

  • zIndex: number (层级控制)

  1. 行为控制

  • closeOnClick: boolean (点击后自动关闭)

  • showIcons: boolean (全局图标显示开关)

事件 (Emits)

  1. item-click (携带被点击的 MenuItem 对象)

  2. contextmenu-open (菜单打开时触发)

  3. contextmenu-close (菜单关闭时触发)

  4. before-close (关闭前可拦截)

其他

  1. 键盘导航

    • 方向键导航

    • Enter 确认选择

    • ESC 关闭菜单

  2. 边缘处理

    • 自动翻转子菜单位置

    • 屏幕边界碰撞检测

  3. 可访问性

    • 正确的 ARIA 角色属性

    • 键盘焦点管理

  4. 样式建议

    • 使用 position: fixed 定位

    • 内置过渡动画

    • 提供 CSS 变量主题化

  5. 扩展功能

    • 通过插槽支持自定义菜单项模板

    • 支持多级嵌套子菜单

    • 全局右键事件管理

  6. 最佳实践

    • 在组件挂载时添加全局点击监听

    • 阻止浏览器默认右键菜单

    • 提供 TypeScript 类型定义

建议优先实现核心功能,再逐步扩展高级特性。可通过配置优先 + 插槽扩展的方式平衡灵活性和易用性。

你有更好的建议也可以添加,要注明。组件定义好后给出3个及以上的调用示例。

下面是现有目录

vueAndDeepseek/

├── src/ # 源代码目录

│ ├── assets/ # 静态资源

│ │ ├── base.css

│ │ ├── main.css

│ │ └── logo.svg

│ ├── components/ # 组件目录

│ │ ├── HelloWorld.vue

│ │ ├── TheWelcome.vue

│ │ ├── WelcomeItem.vue

│ │ ├── Progress/

│ │ │ └── Progress.vue

│ │ ├── Accordion/

│ │ ├── BackToTop/

│ │ ├── Card/

│ │ ├── InfiniteScroll/

│ │ ├── Notification/

│ │ ├── Timeline/

│ │ ├── Switch/

│ │ ├── Tabs/

│ │ ├── Sidebar/

│ │ ├── Breadcrumbs/

│ │ ├── MasonryLayout/

│ │ ├── Rating/

│ │ ├── ColorPicker/

│ │ ├── RightClickMenu/

│ │ ├── DatePicker/

│ │ └── icons/

│ ├── router/ # 路由配置

│ │ └── index.js

│ ├── stores/ # Pinia 状态管理

│ │ └── counter.js

│ ├── views/ # 页面组件

│ │ ├── ProgressView.vue

│ │ ├── TabsView.vue

│ │ ├── SwitchView.vue

│ │ ├── TimelineView.vue

│ │ ├── NotificationView.vue

│ │ ├── CardView.vue

│ │ ├── InfiniteScrollView.vue

│ │ ├── BackToTopView.vue

│ │ ├── AccordionView.vue

│ │ ├── SidebarView.vue

│ │ ├── BreadcrumbsView.vue

│ │ ├── MasonryLayoutView.vue

│ │ ├── RatingView.vue

│ │ ├── ColorPickerView.vue

│ │ ├── RightClickMenuView.vue

│ │ ├── DatePickerView.vue

│ │ └── AboutView.vue

│ ├── App.vue # 根组件

│ └── main.js # 应用入口

├── public/ # 公共资源目录

├── index.html # HTML 模板

├── package.json # 项目配置

├── vite.config.js # Vite 配置

└── node_modules/ # 依赖包目录

📘组件代码 src\\components\\RightClickMenu\\RightClickMenu.vue

import{ref,onMounted,onUnmounted}from\'vue\';constprops=defineProps({items:{type:Array,required:true,default:()=>[]},theme:{type:String,default:\'light\'},customClass:{type:String,default:\'\'},zIndex:{type:Number,default:1000},closeOnClick:{type:Boolean,default:true},showIcons:{type:Boolean,default:true}});constemit=defineEmits([\'item-click\',\'contextmenu-open\']);constvisible=ref(false);constposition=ref({x:0,y:0});constmenuRef=ref(null);//显示菜单constshow=(event)=>{event.preventDefault();position.value={x:event.clientX,y:event.clientY};visible.value=true;emit(\'contextmenu-open\');//添加全局点击事件监听document.addEventListener(\'click\',handleClickOutside);};//隐藏菜单consthide=()=>{visible.value=false;document.removeEventListener(\'click\',handleClickOutside);};//处理菜单项点击consthandleItemClick=(item)=>{if(item.disabled)return;emit(\'item-click\',item);if(item.handler){item.handler(item);}if(props.closeOnClick){hide();}};//处理点击外部consthandleClickOutside=(event)=>{if(menuRef.value&&!menuRef.value.contains(event.target)){hide();}};//组件卸载时清理onUnmounted(()=>{document.removeEventListener(\'click\',handleClickOutside);});//暴露方法给父组件defineExpose({show,hide});{{item.label}}▶
.right-click-menu{position:fixed;background:#ffffff;border:1pxsolid#e4e7ed;border-radius:4px;box-shadow:02px12px0rgba(0,0,0,0.1);padding:5px0;min-width:150px;}.menu-list{margin:0;padding:0;list-style:none;}.menu-item{padding:8px16px;cursor:pointer;display:flex;align-items:center;white-space:nowrap;}.menu-item:hover{background-color:#f5f7fa;}.menu-item.disabled{color:#c0c4cc;cursor:not-allowed;}.menu-divider{height:1px;margin:5px0;background-color:#e4e7ed;}.item-icon{margin-right:8px;width:16px;text-align:center;}.item-label{flex:1;}.submenu-arrow{margin-left:8px;font-size:12px;}/*深色主题*/.theme-dark{background:#303133;border-color:#606266;}.theme-dark.menu-item{color:#ffffff;}.theme-dark.menu-item:hover{background-color:#409EFF;}.theme-dark.menu-divider{background-color:#606266;}.theme-dark.menu-item.disabled{color:#909399;}

📘定义组件 src\\views\\RightClickMenuView.vue

import{ref}from\'vue\';importRightClickMenufrom\'../components/RightClickMenu/RightClickMenu.vue\';constmenuRef1=ref(null);constmenuRef2=ref(null);constmenuRef3=ref(null);//基础菜单项配置constbasicMenuItems=[{id:\'copy\',label:\'复制\',icon:\'icon-copy\',handler:()=>console.log(\'复制\')},{id:\'paste\',label:\'粘贴\',icon:\'icon-paste\'},{divider:true},{id:\'delete\',label:\'删除\',icon:\'icon-delete\'}];//带子菜单的配置constnestedMenuItems=[{id:\'file\',label:\'文件\',children:[{id:\'new\',label:\'新建\',icon:\'icon-new\'},{id:\'open\',label:\'打开\',icon:\'icon-open\'}]},{id:\'edit\',label:\'编辑\',children:[{id:\'copy\',label:\'复制\',icon:\'icon-copy\'},{id:\'paste\',label:\'粘贴\',icon:\'icon-paste\',disabled:true}]}];//自定义菜单项constcustomMenuItems=[{id:\'share\',label:\'分享到\',children:[{id:\'wechat\',label:\'微信\',icon:\'icon-wechat\'},{id:\'weibo\',label:\'微博\',icon:\'icon-weibo\'}]},{divider:true},{id:\'delete\',label:\'删除\',icon:\'icon-delete\',disabled:true}];//事件处理函数consthandleContextMenu1=(event)=>{event.preventDefault();menuRef1.value?.show(event);};consthandleContextMenu2=(event)=>{event.preventDefault();menuRef2.value?.show(event);};consthandleContextMenu3=(event)=>{event.preventDefault();menuRef3.value?.show(event);};consthandleItemClick=(item)=>{console.log(\'菜单项被点击:\',item);};consthandleContextMenuOpen=()=>{console.log(\'右键菜单已打开\');};

右键菜单示例

基础用法

在此区域右键点击查看基础菜单

多级菜单+深色主题

在此区域右键点击查看多级菜单

自定义样式

在此区域右键点击查看自定义样式菜单

.right-click-menu-demo{padding:20px;}.demo-box{margin:20px;padding:40px;border:1pxsolid#ddd;border-radius:8px;background:#f5f7fa;cursor:context-menu;}.demo-boxh3{margin:0015px0;color:#333;}.demo-boxp{margin:0;color:#666;}/*深色主题示例*/.demo-box.dark{background:#303133;border-color:#606266;}.demo-box.darkh3,.demo-box.darkp{color:#fff;}/*自定义样式示例*/.demo-box.custom{background:linear-gradient(135deg,#42d39225%,#647eff);border:none;}.demo-box.customh3,.demo-box.customp{color:#fff;}/*自定义菜单样式*/:deep(.custom-menu){background:rgba(255,255,255,0.95);backdrop-filter:blur(10px);border:none;box-shadow:04px20pxrgba(0,0,0,0.15);}:deep(.custom-menu.menu-item:hover){background-color:#42d392;color:white;}

📚代码测试

正常

📚测试代码正常跑通,附其他基本代码

  • 添加路由

  • 页面展示入口

📘编写路由 src\\router\\index.js

图片[2]-DeepSeek+Vue:打造丝滑的右键菜单(RightClickMenu)-趣考网

import{createRouter,createWebHistory}from\'vue-router\'importRightClickMenuViewfrom\'../views/RightClickMenuView.vue\'constrouter=createRouter({history:createWebHistory(import.meta.env.BASE_URL),routes:[{path:\'/\',name:\'progress\',component:()=>import(\'../views/ProgressView.vue\'),},{path:\'/tabs\',name:\'tabs\',//routelevelcode-splitting//thisgeneratesaseparatechunk(About.[hash].js)forthisroute//whichislazy-loadedwhentherouteisvisited.//标签页(Tabs)component:()=>import(\'../views/TabsView.vue\'),},{path:\'/accordion\',name:\'accordion\',//折叠面板(Accordion)component:()=>import(\'../views/AccordionView.vue\'),},{path:\'/timeline\',name:\'timeline\',//时间线(Timeline)component:()=>import(\'../views/TimelineView.vue\'),},{path:\'/backToTop\',name:\'backToTop\',component:()=>import(\'../views/BackToTopView.vue\')},{path:\'/notification\',name:\'notification\',component:()=>import(\'../views/NotificationView.vue\')},{path:\'/card\',name:\'card\',component:()=>import(\'../views/CardView.vue\')},{path:\'/infiniteScroll\',name:\'infiniteScroll\',component:()=>import(\'../views/InfiniteScrollView.vue\')},{path:\'/switch\',name:\'switch\',component:()=>import(\'../views/SwitchView.vue\')},{path:\'/sidebar\',name:\'sidebar\',component:()=>import(\'../views/SidebarView.vue\')},{path:\'/breadcrumbs\',name:\'breadcrumbs\',component:()=>import(\'../views/BreadcrumbsView.vue\')},{path:\'/masonryLayout\',name:\'masonryLayout\',component:()=>import(\'../views/MasonryLayoutView.vue\')},{path:\'/rating\',name:\'rating\',component:()=>import(\'../views/RatingView.vue\')},{path:\'/datePicker\',name:\'datePicker\',component:()=>import(\'../views/DatePickerView.vue\')},{path:\'/colorPicker\',name:\'colorPicker\',component:()=>import(\'../views/ColorPickerView.vue\')},{path:\'/rightClickMenu\',name:\'rightClickMenu\',component:RightClickMenuView}],})exportdefaultrouter

📘编写展示入口 src\\App.vue

图片[3]-DeepSeek+Vue:打造丝滑的右键菜单(RightClickMenu)-趣考网

import{RouterLink,RouterView}from\'vue-router\'importHelloWorldfrom\'./components/HelloWorld.vue\'
header{line-height:1.5;max-height:100vh;}.logo{display:block;margin:0auto2rem;}nav{width:100%;font-size:12px;text-align:center;margin-top:2rem;}nava.router-link-exact-active{color:var(--color-text);}nava.router-link-exact-active:hover{background-color:transparent;}nava{display:inline-block;padding:01rem;border-left:1pxsolidvar(--color-border);}nava:first-of-type{border:0;}@media(min-width:1024px){header{display:flex;place-items:center;padding-right:calc(var(--section-gap)/2);}.logo{margin:02rem00;}header.wrapper{display:flex;place-items:flex-start;flex-wrap:wrap;}nav{text-align:left;margin-left:-1rem;font-size:1rem;padding:1rem0;margin-top:1rem;}}

📚页面效果

图片[1]-DeepSeek+Vue:打造丝滑的右键菜单(RightClickMenu)-趣考网

总结

通过DeepSeek与Vue.js的强强联合,我们成功创建了一款体验丝滑、功能全面的右键菜单组件。DeepSeek的智能化代码生成和优化建议,不仅简化了开发流程,还提升了组件的性能和稳定性。Vue.js的组件化开发特性,使得右键菜单组件具备了高度的复用性和可维护性,便于在不同项目和场景中进行快速部署和调整。本文详细介绍了从需求分析、组件设计、事件监听与处理,到样式美化和动画效果的实现,再到通过DeepSeek进行代码优化和性能提升的完整开发流程。实践表明,DeepSeek与Vue.js的结合,为开发者提供了强大的开发工具和灵活的设计空间,能够轻松打造出符合用户期待的高质量右键菜单组件。

© 版权声明
THE END
编程
# DeepSeek
喜欢就支持一下吧
点赞10 分享
相关推荐