eltable-右键菜单

index.vue

<script setup>
    import { computed, unref } from 'vue';

    const props = defineProps({
        menuConfig: {
            type: Array,
            required: true
        },
        virtualRef: Function,
        zIndex: {
            type: Number,
            default: 1000
        }
    })

    const warpRef = ref()

    const emit = defineEmits(['menu-click'])
    const contextMenuArgs = ref()

    const setWarpRef = (el) => {
        warpRef.value = el
        props.virtualRef(el)
    }


    const classNames = computed(() => {
        return {
        }
    })

    const init = (args) => {
        contextMenuArgs.value = args
    }

    const handleClick = (menu) => {
        warpRef.value.classList.remove('show')

        emit('menu-click', {
            menu,
            ...unref(contextMenuArgs)
        })
    }

    defineExpose({
        init
    })
</script>

<template>
    <Teleport to="body">
        <div class="shadow-lg el-table--context-menu-wrapper" :ref="setWarpRef"
            :style="{ zIndex: zIndex }">
            <div class="w-32 contentBox">
                <div class="box" v-for="(box, index1) in menuConfig" :key="index1">
                    <div class="itemBox" v-for="(itemBox, index2) in box" :key="index2" @click="handleClick(itemBox)">
                        {{ itemBox.name }}
                    </div>
                </div>
            </div>
        </div>
    </Teleport>
</template>

<style lang="scss" scoped>
    .el-table--context-menu-wrapper {
        position: absolute;
        top: 0;
        left: 0;
        border-radius: 5px;
        font-size: 12px;
        // border: 1px solid #dadce0;
        // box-shadow: 3px 3px 6px -2px rgba(223, 221, 221, 0.6);
        padding: 5px 0px;
        -webkit-user-select: none;
        -moz-user-select: none;
        -ms-user-select: none;
        user-select: none;
        background-color: #fff;
        display: none;

        &.show {
            display: block;
        }

        .contentBox {
            .box {
                border-bottom-width: 1px;


                .itemBox {
                    padding: 0 25px;
                    cursor: pointer;
                    line-height: 30px;

                    &:hover {
                        background-color: #f5f7fa
                    }
                }
            }

            .box:last-child {
                border-bottom-width: 0;
            }
        }
    }
</style>

hook.js

使用

<template>
    <div class="app-container">
        <el-table border :data="tableData" style="width: 100%" @cell-contextmenu="handleContextMenu">
            <el-table-column prop="date" label="Date" width="180" />
            <el-table-column prop="name" label="Name" width="180" />
            <el-table-column prop="address" label="Address" />
        </el-table>
        <ContextMenu
            :menu-config="menuConfig"
            @menu-click="contextMenuClickEvent"
            :virtual-ref="contextMenuVirtualRef"
            ref="contextMenuRef" />
    </div>
</template>

<script setup>
    import ContextMenu from "@/components/ContextMenu/index.vue";
    import contextMenuHook from "@/components/ContextMenu/hook";

    const { handleContextMenu, contextMenuVirtualRef, contextMenuRef } = contextMenuHook()

    const menuConfig = ref([
        [
            { code: 'copy', name: '复制', prefixIcon: 'vxe-icon-copy', className: 'my-copy-item' }
        ],
        [
            { code: 'remove', name: '删除', prefixIcon: 'vxe-icon-delete-fill color-red' },
            {
                name: '筛选',
                children: [
                    { code: 'clearFilter', name: '清除筛选' },
                    { code: 'filterSelect', name: '按所选单元格的值筛选' }
                ]
            },
            {
                code: 'sort',
                name: '排序',
                prefixIcon: 'vxe-icon-sort color-blue',
                children: [
                    { code: 'clearSort', name: '清除排序' },
                    { code: 'sortAsc', name: '升序', prefixIcon: 'vxe-icon-sort-alpha-asc color-orange' },
                    { code: 'sortDesc', name: '倒序', prefixIcon: 'vxe-icon-sort-alpha-desc color-orange' }
                ]
            },
            { code: 'print', name: '打印', disabled: true }
        ]
    ])

    const contextMenuClickEvent = ({ menu, row, column }) => {
        console.log(999, menu.code, column);
    }

    const tableData = [
        {
            date: '2016-05-03',
            name: 'Tom',
            address: 'No. 189, Grove St, Los Angeles',
        },
        {
            date: '2016-05-02',
            name: 'Tom',
            address: 'No. 189, Grove St, Los Angeles',
        },
        {
            date: '2016-05-04',
            name: 'Tom',
            address: 'No. 189, Grove St, Los Angeles',
        },
        {
            date: '2016-05-01',
            name: 'Tom',
            address: 'No. 189, Grove St, Los Angeles',
        },
    ]
</script>

<style lang="scss" scoped></style>

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值