Vue中實(shí)現(xiàn)動(dòng)態(tài)右鍵菜單的示例代碼
在前端開(kāi)發(fā)中,自定義右鍵菜單是一種常見(jiàn)的交互方式,它能夠?yàn)橛脩籼峁└嗟墓δ苓x項(xiàng)。在本文中,將探討如何在 Vue 中實(shí)現(xiàn)一個(gè)動(dòng)態(tài)右鍵菜單,該菜單能夠根據(jù)用戶點(diǎn)擊位置動(dòng)態(tài)調(diào)整其顯示位置,確保菜單始終在瀏覽器窗口的可視區(qū)域內(nèi)。
實(shí)現(xiàn)目標(biāo)
- 右鍵點(diǎn)擊頁(yè)面時(shí)顯示自定義菜單。
- 菜單根據(jù)點(diǎn)擊位置動(dòng)態(tài)定位。
- 確保菜單不會(huì)超出瀏覽器窗口的可視區(qū)域。(超出窗口頂部或者底部?jī)?yōu)化)
實(shí)現(xiàn)步驟
1. 創(chuàng)建 Vue 組件模板
首先,編寫(xiě) Vue 組件的模板部分:
<template> <div v-if="visible"> <a-menu class="contextmenu" :style="style" @click="handleClick"> <a-menu-item v-for="item in list" :key="item.key"> <span>{{ item.text }}</span> </a-menu-item> </a-menu> </div> </template>
在這個(gè)模板中,使用 v-if
指令控制菜單的顯示與隱藏,并使用 :style
綁定菜單的動(dòng)態(tài)樣式。
2. 編寫(xiě)組件腳本
接下來(lái)是組件的腳本部分:
<script> export default { name: "ContextMenu", props: { visible: { type: Boolean, default: false, }, list: { type: Array, required: true, default: () => [], }, }, data() { return { left: 0, top: 0, target: null, }; }, computed: { style() { return { left: this.left + "px", top: this.top + "px", }; }, }, created() { const clickHandler = () => this.closeMenu(); const contextMenuHandler = (e) => { e.preventDefault(); this.setPosition(e); }; window.addEventListener("click", clickHandler); window.addEventListener("contextmenu", contextMenuHandler); this.$emit("hook:beforeDestroy", () => { window.removeEventListener("click", clickHandler); window.removeEventListener("contextmenu", contextMenuHandler); }); }, methods: { closeMenu() { this.$emit("update:visible", false); }, setPosition(e) { // 獲取菜單的寬高 const menu = document.querySelector(".contextmenu"); const menuHeight = menu.offsetHeight; // 獲取窗口的可視高度 const windowHeight = window.innerHeight; this.left = e.clientX; // 計(jì)算菜單的上邊位置 if (e.clientY + menuHeight > windowHeight) { const top = e.clientY - menuHeight; if (top < 0) { this.top = 0; // 確保菜單不會(huì)超出頂部 } else { // 如果菜單的底部超出了窗口的底部 this.top = top; } } else { // 如果菜單的底部沒(méi)有超出窗口的底部 this.top = e.clientY; } this.target = e.target; }, handleClick({ key }) { const _component = this.list.filter((item) => item.key === key)[0] .component; if (_component) { this.$emit("contextMenuClick", _component, key); } this.closeMenu(); }, }, }; </script>
詳細(xì)解釋
setPosition 方法
setPosition
方法用于根據(jù)用戶點(diǎn)擊的位置動(dòng)態(tài)調(diào)整菜單的位置,確保菜單始終在可視區(qū)域內(nèi)。
setPosition(e) { // 獲取菜單的寬高 const menu = document.querySelector(".contextmenu"); const menuHeight = menu.offsetHeight; // 獲取窗口的可視高度 const windowHeight = window.innerHeight; this.left = e.clientX; // 計(jì)算菜單的上邊位置 if (e.clientY + menuHeight > windowHeight) { const top = e.clientY - menuHeight; if (top < 0) { this.top = 0; // 確保菜單不會(huì)超出頂部 } else { // 如果菜單的底部超出了窗口的底部 this.top = top; } } else { // 如果菜單的底部沒(méi)有超出窗口的底部 this.top = e.clientY; } this.target = e.target; }
- 相加:通過(guò)
e.clientY + menuHeight
計(jì)算菜單底部的位置,如果大于windowHeight
,則表示菜單超出了窗口底部,需要調(diào)整位置。 - 相減:通過(guò)
e.clientY - menuHeight
將菜單位置調(diào)整到鼠標(biāo)點(diǎn)擊位置的上方,確保菜單不會(huì)超出窗口底部。 - clientY:鼠標(biāo)點(diǎn)擊位置的垂直坐標(biāo),相對(duì)于視口。
- offsetHeight:菜單元素的高度,包括內(nèi)容的高度、內(nèi)邊距和邊框。
事件處理
在 created
生命周期鉤子中,添加了 click
和 contextmenu
事件監(jiān)聽(tīng)器。
created() { const clickHandler = () => this.closeMenu(); const contextMenuHandler = (e) => { this.setPosition(e); }; window.addEventListener("click", clickHandler); window.addEventListener("contextmenu", contextMenuHandler); this.$emit("hook:beforeDestroy", () => { window.removeEventListener("click", clickHandler); window.removeEventListener("contextmenu", contextMenuHandler); }); }
- clickHandler:點(diǎn)擊頁(yè)面時(shí),關(guān)閉菜單。
- contextMenuHandler:右鍵點(diǎn)擊時(shí),阻止默認(rèn)的右鍵菜單行為,并根據(jù)點(diǎn)擊位置設(shè)置菜單的位置。
樣式部分
<style lang="scss" scoped> .contextmenu { position: fixed; z-index: 1000; border-radius: 4px; border: 1px lightgrey solid; box-shadow: 4px 4px 10px lightgrey !important; } </style>
總結(jié)
通過(guò)以上代碼,實(shí)現(xiàn)了一個(gè)動(dòng)態(tài)右鍵菜單。這個(gè)菜單能夠根據(jù)用戶的點(diǎn)擊位置動(dòng)態(tài)調(diào)整其顯示位置,確保菜單始終在瀏覽器窗口的可視區(qū)域內(nèi)。這樣的實(shí)現(xiàn)可以提升用戶體驗(yàn),使應(yīng)用更加友好和易用。
到此這篇關(guān)于Vue中實(shí)現(xiàn)動(dòng)態(tài)右鍵菜單的示例代碼的文章就介紹到這了,更多相關(guān)Vue 動(dòng)態(tài)右鍵菜單內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- vue3實(shí)現(xiàn)動(dòng)態(tài)路由及菜單
- vue3實(shí)現(xiàn)動(dòng)態(tài)側(cè)邊菜單欄的幾種方式簡(jiǎn)單總結(jié)
- Vue如何根據(jù)角色獲取菜單動(dòng)態(tài)添加路由
- vue3+element-plus動(dòng)態(tài)路由菜單示例代碼
- Vue3+Element?Plus實(shí)現(xiàn)動(dòng)態(tài)標(biāo)簽頁(yè)以及右鍵菜單功能
- 詳解Vue3如何加載動(dòng)態(tài)菜單
- vue實(shí)現(xiàn)三級(jí)聯(lián)動(dòng)動(dòng)態(tài)菜單
- vue后臺(tái)管理如何配置動(dòng)態(tài)路由菜單
- vue如何從后臺(tái)獲取數(shù)據(jù)生成動(dòng)態(tài)菜單列表
相關(guān)文章
Vue2?Dialog彈窗函數(shù)式調(diào)用實(shí)踐示例
這篇文章主要為大家介紹了Vue2?Dialog彈窗函數(shù)式調(diào)用實(shí)踐示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01vue將數(shù)字轉(zhuǎn)為中文大寫(xiě)金額方式
這篇文章主要介紹了vue將數(shù)字轉(zhuǎn)為中文大寫(xiě)金額方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07vue 實(shí)現(xiàn)超長(zhǎng)文本截取,懸浮框提示
這篇文章主要介紹了vue 實(shí)現(xiàn)超長(zhǎng)文本截取,懸浮框提示,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-07-07vue?Router(v3.x)?路由傳參的三種方式場(chǎng)景分析
vue?路由傳參的使用場(chǎng)景一般都是應(yīng)用在父路由跳轉(zhuǎn)到子路由時(shí),攜帶參數(shù)跳轉(zhuǎn),傳參方式可劃分為?params?傳參和?query?傳參,而?params?傳參又可分為在?url?中顯示參數(shù)和不顯示參數(shù)兩種方式,這就是vue路由傳參的三種方式,感興趣的朋友跟隨小編一起看看吧2023-07-07Vue監(jiān)聽(tīng)數(shù)據(jù)渲染DOM完以后執(zhí)行某個(gè)函數(shù)詳解
今天小編就為大家分享一篇Vue監(jiān)聽(tīng)數(shù)據(jù)渲染DOM完以后執(zhí)行某個(gè)函數(shù)詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-09-09