vue实现点击出现按钮菜单
先上效果图
父组件代码
<template>
<div class="app-container">
<div @click="popup($event, item)">
点击
</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: '删除'
}], //菜单数据
}
},
components: {
PopupMenu,
},
methods: {
popup(event, item) {
this.$refs.popup.show(event); //调用子组件的show方法,用于显示弹出式菜单,引用组件时,需要 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; //鼠标点击的x坐标
let y = event.y; //鼠标点击的y坐标
let menuWidth = 150; //菜单宽度,这个与.popup-menu样式对应的宽度一致
let menuHeight = this.menuData.length * 30 + 20; //菜单高度,根据菜单项自动计算的高度
this.clientX = (parseFloat(x) - 10) + "px";
this.clientY = (parseFloat(y) + 10) + "px";
let windowWidth = document.documentElement.clientWidth; // 实时屏幕宽度
let windowHeight = document.documentElement.clientHeight; // 实时屏幕高度
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); // 添加关闭事件
},
closeMenu() {
// console.log("销毁监听事件。");
document.removeEventListener("click", this.closeMenu, false); //销毁关闭事件
this.showMenu = false;
},
itemClick(event) {
let id = event.target.getAttribute("data-id"); //获取菜单项id
this.$emit('menuClick', id); //传参调用父组件事件,让父组件知道是点击到哪个菜单项
}
}
}
</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>