80 lines
2.3 KiB
Vue
80 lines
2.3 KiB
Vue
![]() |
<template>
|
|||
|
<div class="my-dropdown" @click.stop="trigger == 'click' ? (showMenu = !showMenu) : ''"
|
|||
|
@mouseenter="trigger == 'hover' ? (showMenu = true) : ''"
|
|||
|
@mouseleave="trigger == 'hover' ? (showMenu = false) : ''" ref="myDropDdown" >
|
|||
|
<div class="tip-text" ref="tipText">
|
|||
|
<slot></slot>
|
|||
|
</div>
|
|||
|
<slot name="list"></slot>
|
|||
|
</div>
|
|||
|
</template>
|
|||
|
<script>
|
|||
|
import emitter from "./emitter";
|
|||
|
export default {
|
|||
|
name: "MyDropdown",
|
|||
|
componentName: "MyDropdown",
|
|||
|
mixins: [emitter],
|
|||
|
props: {
|
|||
|
// 触发显示方式
|
|||
|
trigger: {
|
|||
|
type: String,
|
|||
|
default: "click",
|
|||
|
},
|
|||
|
// 下来菜单的出现位置(上方,下方)
|
|||
|
placement: {
|
|||
|
type: String,
|
|||
|
default: "bottom",
|
|||
|
validator: function (value) {
|
|||
|
// 这个值必须匹配下列字符串中的一个
|
|||
|
return ["bottom", "top"].includes(value);
|
|||
|
},
|
|||
|
},
|
|||
|
},
|
|||
|
data () {
|
|||
|
return {
|
|||
|
//控制菜单是否显示
|
|||
|
showMenu: false,
|
|||
|
};
|
|||
|
},
|
|||
|
mounted () {
|
|||
|
//初始化自定义事件
|
|||
|
this.initEvent();
|
|||
|
},
|
|||
|
methods: {
|
|||
|
// 初始化
|
|||
|
initEvent () {
|
|||
|
//订阅当item点击的时候,发布on-click事件,告知外部
|
|||
|
this.$on("item-click", (params) => {
|
|||
|
this.$emit("on-click", params);
|
|||
|
this.showMenu = false;
|
|||
|
});
|
|||
|
//空白点击要隐藏菜单,需要执行的函数需要绑定this指向
|
|||
|
this.handleEmptyDomElementClickBindThis =
|
|||
|
this.handleEmptyDomElementClick.bind(this);
|
|||
|
window.addEventListener("click", this.handleEmptyDomElementClickBindThis);
|
|||
|
},
|
|||
|
// 处理空白区域点击,隐藏菜单列表
|
|||
|
handleEmptyDomElementClick (e) {
|
|||
|
if (!Array.from(this.$refs.myDropDdown.childNodes).includes(e.target)) {
|
|||
|
this.showMenu = false;
|
|||
|
}
|
|||
|
},
|
|||
|
},
|
|||
|
beforeDestroy () {
|
|||
|
// 移除window上面的事件
|
|||
|
window.removeEventListener(this.handleEmptyDomElementClickBindThis);
|
|||
|
},
|
|||
|
watch: {
|
|||
|
//变化的时候,通知子组件隐藏菜单列表
|
|||
|
showMenu () {
|
|||
|
this.broadcast("MyDropdownMenu", "set-menu-status", this.showMenu);
|
|||
|
},
|
|||
|
},
|
|||
|
};
|
|||
|
</script>
|
|||
|
<style lang="scss" scoped>
|
|||
|
.my-dropdown {
|
|||
|
position: relative;
|
|||
|
}
|
|||
|
</style>
|