vue實(shí)現(xiàn)點(diǎn)擊出現(xiàn)按鈕菜單問題
更新時(shí)間:2026年03月06日 16:21:45 作者:心明自知
文章主要介紹了如何在Vue中實(shí)現(xiàn)點(diǎn)擊按鈕顯示菜單的功能,父組件負(fù)責(zé)觸發(fā)事件,子組件負(fù)責(zé)渲染菜單,通過事件冒泡和狀態(tài)管理,實(shí)現(xiàn)了菜單的顯示和隱藏,代碼示例簡潔明了,適合初學(xué)者參考
vue點(diǎn)擊出現(xiàn)按鈕菜單

父組件代碼
<template>
<div class="app-container">
<div @click="popup($event, item)">
點(diǎn)擊
</div>
<!-- 單擊菜單 -->
<popup-menu ref="popup" :menuData="menuData" @menuClick="menuClick(arguments)">
</popup-menu>
</div>
<script>
import PopupMenu from '@/views/popupMenu';
export default {
data(){
return{
menuData: [{
id: 'edit',
name: '編輯'
}, {
id: 'delete',
name: '刪除'
}], //菜單數(shù)據(jù)
}
},
components: {
PopupMenu,
},
methods: {
popup(event, item) {
this.$refs.popup.show(event); //調(diào)用子組件的show方法,用于顯示彈出式菜單,引用組件時(shí),需要 ref="child"
},
menuClick(args) {
// 子組件的方法 @menuClick="menuClick(arguments)" 注意menuClick()里面一定要填寫arguments,用于接受子組件的傳參
let type = args[0];
if (type == 'edit') {
console.log('編輯');
} else if (type == 'delete') {
console.log('刪除');
}
},
}
}
</script>
</template>
菜單組件代碼
<template>
<div v-if="showMenu" class="position-fixed popup-menu flex flex-col" :style="{top:clientY, left:clientX}">
<div v-for="item in menuData" class="popup-menu-item pointer flex flex-center-cz padding-left-m" :data-id="item.id"
@click="itemClick">{{item.name}}</div>
</div>
</template>
<script>
export default {
name: 'PopupMenu',
props: {
menuData: {},
},
data() {
return {
showMenu: false,
clientX: '',
clientY: '',
}
},
methods: {
show(event) {
// console.log("父組件傳過來的event", event);
let x = event.x; //鼠標(biāo)點(diǎn)擊的x坐標(biāo)
let y = event.y; //鼠標(biāo)點(diǎn)擊的y坐標(biāo)
let menuWidth = 150; //菜單寬度,這個(gè)與.popup-menu樣式對應(yīng)的寬度一致
let menuHeight = this.menuData.length * 30 + 20; //菜單高度,根據(jù)菜單項(xiàng)自動(dòng)計(jì)算的高度
this.clientX = (parseFloat(x) - 10) + "px";
this.clientY = (parseFloat(y) + 10) + "px";
let windowWidth = document.documentElement.clientWidth; // 實(shí)時(shí)屏幕寬度
let windowHeight = document.documentElement.clientHeight; // 實(shí)時(shí)屏幕高度
if (parseFloat(x) + menuWidth > windowWidth) {
this.clientX = (parseFloat(windowWidth) - menuWidth - 50) + "px";
}
if (parseFloat(y) + menuHeight > windowHeight) {
this.clientY = (parseFloat(windowHeight) - menuHeight - 50) + "px";
}
this.showMenu = true;
event.stopPropagation(); //阻止事件冒泡
document.addEventListener("click", this.closeMenu, false); // 添加關(guān)閉事件
},
closeMenu() {
// console.log("銷毀監(jiān)聽事件。");
document.removeEventListener("click", this.closeMenu, false); //銷毀關(guān)閉事件
this.showMenu = false;
},
itemClick(event) {
let id = event.target.getAttribute("data-id"); //獲取菜單項(xiàng)id
this.$emit('menuClick', id); //傳參調(diào)用父組件事件,讓父組件知道是點(diǎn)擊到哪個(gè)菜單項(xiàng)
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.position-fixed {
position: fixed;
}
.popup-menu {
width: 80px;
padding: 10px;
border-radius: 10px;
background-color: #fff;
border-style: solid;
border-width: 1px;
border-color: rgba(0, 0, 0, .2);
z-index: 999;
}
.popup-menu-item {
height: 20px;
}
.popup-menu-item:hover {
border-radius: 5px;
background: rgba(0, 0, 0, .1);
}
</style>
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
您可能感興趣的文章:
- vue實(shí)現(xiàn)點(diǎn)擊按鈕input保持聚焦?fàn)顟B(tài)的示例代碼
- 關(guān)于VUE點(diǎn)擊父組件按鈕跳轉(zhuǎn)到子組件的問題及解決方案
- vue實(shí)現(xiàn)button按鈕的重復(fù)點(diǎn)擊指令方式
- Vue3實(shí)現(xiàn)點(diǎn)擊按鈕實(shí)現(xiàn)文字變色功能
- vue+elementUI實(shí)現(xiàn)點(diǎn)擊左右箭頭切換按鈕功能
- 使用Vue實(shí)現(xiàn)點(diǎn)擊按鈕小球加入購物車動(dòng)畫
- vue3按鈕點(diǎn)擊頻率控制的實(shí)現(xiàn)示例
- vue3點(diǎn)擊按鈕下載文件功能的代碼實(shí)現(xiàn)
相關(guān)文章
詳解vue前后臺數(shù)據(jù)交互vue-resource文檔
本篇文章主要介紹了vue前后臺數(shù)據(jù)交互vue-resource文檔,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07
Vue實(shí)現(xiàn)數(shù)字輸入框中分割手機(jī)號碼的示例
本篇文章主要介紹了Vue實(shí)現(xiàn)數(shù)字輸入框中分割手機(jī)號碼的示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-10-10
為什么Vue3.0使用Proxy實(shí)現(xiàn)數(shù)據(jù)監(jiān)聽(defineProperty表示不背這個(gè)鍋)
這篇文章主要介紹了為什么Vue3.0使用Proxy實(shí)現(xiàn)數(shù)據(jù)監(jiān)聽?defineProperty表示不背這個(gè)鍋,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10
vue?LogicFlow自定義邊實(shí)現(xiàn)示例詳解
這篇文章主要為大家介紹了vue?LogicFlow自定義邊示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01
vue項(xiàng)目中使用lib-flexible解決移動(dòng)端適配的問題解決
這篇文章主要介紹了vue項(xiàng)目中使用lib-flexible解決移動(dòng)端適配的問題解決,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-08-08
buildAdmin開源項(xiàng)目引入四種圖標(biāo)方式詳解
這篇文章主要為大家介紹了buildAdmin開源項(xiàng)目引入四種圖標(biāo)方式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02
基于Vue實(shí)現(xiàn)頁面切換左右滑動(dòng)效果
這篇文章主要為大家詳細(xì)介紹了基于Vue實(shí)現(xiàn)頁面切換左右滑動(dòng)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08

