vue - 选项卡右击下拉框

在 element-ui 环境下,给选项卡添加右击事件,是相当麻烦的一件事情,

主要是麻烦,很多东西都需要注意,并没有太多难点。

注意项

el-tabs 的右击事件

事件的名称是 contextmenu.prevent.native,这个很快就能找到,需要注意的是:

选项卡整个头部都能触发右击事件,需要过滤出哪些事件是由选项卡触发的。

右击下拉框实现方案

只需要在界面隐藏一个下拉框,点击的时候,获取点击位置信息,将下拉框显示在该位置即可。

获取 e.target 的 clientX/clientY 属性,动态控制面板的 left/top 即可,

这种方式,也可以用在很多吸附弹窗上,还需要注意的是 z-index,避免沉在界面底部。

关闭下拉框

弹出下拉框之后,需要有一个对应的关闭事件,不论点击哪里,都要触发关闭事件。

这时候,要给 windows 对象,添加 mousedown 事件。

mousedown 事件冲突

添加 mousedown 事件之后,就会发现下拉框中的点击事件,是触发不了的;

因此,要通过 e.target 的属性,判断点击事件是否属于下拉框。

代码样例

下面只包含核心代码,可能有一些错误,照着意思改改。

<template>
  <div style="">
    <div v-show="dropdown_visible" :style="style" class="sea-dropdown-menu">
      <p class="el-dropdown-menu__item" id="sea-tabs-close-current">关闭当前</p>
      <p class="el-dropdown-menu__item" id="sea-tabs-close-left">关闭左边</p>
      <p class="el-dropdown-menu__item" id="sea-tabs-close-right">关闭右边</p>
      <hr/>
      <p class="el-dropdown-menu__item" id="sea-tabs-close-other">关闭其他</p>
      <p class="el-dropdown-menu__item" id="sea-tabs-close-all">关闭所有</p>
    </div>

    <el-tabs type="card" v-model="current_tabs_name"
             @contextmenu.prevent.native="onTabRightClick">
		<el-tab-pane label="用户管理" name="first">用户管理</el-tab-pane>
    </el-tabs>
  </div>
</template>

<script>

/**
 * 中央选项卡
 */
export default {
    name: "center-tabs"
    , data() {
        return {
            // 右击菜单可见性
            dropdown_visible: false
            // 触发下拉事件的选项卡 name
            , dropdown_name: undefined
            // 右击菜单位置
            , left: undefined
            // 右击菜单位置
            , top: undefined

        }
    },
    computed: {
        /**
         * 样式
         */
        style: function () {
            return "left: " + this.left + "px; top: " + this.top + "px;";
        }
    },
    mounted() {
        // 落下鼠标时,需要移除展开的右击菜单
        window.addEventListener('mousedown', this.onWindowsMousedown);
    },
    methods: {       
        /**
         * 关闭选项卡右击菜单
         *
         * 下拉列表的点击事件与当前事件冲突,在这个事件里触发点击事件
         */
        onWindowsMousedown: function (e) {
            let clazz = e.target.getAttribute('class');
            let id = e.target.getAttribute('id');
            if (clazz === 'el-dropdown-menu__item') {
                // todo sth.
            }

            this.dropdown_visible = false;
            this.dropdown_name = undefined;
        },

        /**
         * 右击事件 - 打开选项卡右击菜单
         *
         * name 记录在标签的 aria-controls 字段,格式为 "pane-[name]"
         *
         * @param e 事件
         */
        onTabRightClick(e) {
            if (e.target.id !== '') {
                let controls = e.target.getAttribute('aria-controls');
                if (controls.length > 5) {
                    this.dropdown_name = controls.substring(5);
                    console.log(this.dropdown_name);
                    this.dropdown_visible = true;
                    this.left = e.clientX;
                    this.top = e.clientY;
                } else {
                    // 不合常理的右击事件
                    console.error('unknown aria-controls: ' + controls);
                }
            }
        }
    }
    , destroyed() {
        // 移除鼠标落下的侦听事件
        this.dropdown_visible = false;
        window.removeEventListener('mousedown', this.onWindowsMousedown);
    }
}
</script>

<style scoped>
.sea-dropdown-menu {
    position: fixed;
    width: 150px;
    background-color: #fff;
    z-index: 1024;
    border-radius: 3px;
    -webkit-box-shadow: 1px 2px 10px #ccc;
    box-shadow: 1px 2px 10px #ccc;
}
</style>

posted on 2024-10-24 15:18  疯狂的妞妞  阅读(9)  评论(0编辑  收藏  举报

导航