沃梦达 / IT编程 / 前端开发 / 正文

Vue el-table实现右键菜单功能

下面我详细讲解一下“Vue el-table实现右键菜单功能”的完整攻略。

下面我详细讲解一下“Vue el-table实现右键菜单功能”的完整攻略。

背景介绍

在Vue项目开发中,经常需要使用el-table来展示数据,如果需要实现右键菜单功能,该怎么做呢?本攻略将介绍如何使用Vue el-table和自定义指令来实现右键菜单功能。

准备工作

首先,我们需要安装element-ui组件库,并在Vue项目中引入它。具体引入方式可以参考element-ui官方文档。

实现步骤

1. 定义菜单组件

我们需要定义一个菜单组件,用来展示右键菜单内容。可以使用element-ui中的Dropdown Menu组件来实现。

具体定义方式如下:

<template>
  <el-dropdown-menu>
    <el-dropdown-item v-for="(menu, index) in menus" :key="index" @click="handleMenuClick(index)">{{ menu.text }}</el-dropdown-item>
  </el-dropdown-menu>
</template>

<script>
export default {
  props: {
    menus: {
      type: Array,
      default: () => []
    }
  },
  methods: {
    handleMenuClick(index) {
      this.$emit('menu-click', index);
    }
  }
}
</script>

在上面代码中,我们定义了一个menus属性,用来传递菜单列表。当菜单被点击时,通过handleMenuClick方法将当前菜单的索引值传递给父组件。

2. 定义自定义指令

在显示el-table的每一行数据时,为它们绑定一个右键菜单并不是一件方便的事情。这时就需要使用自定义指令来实现。

下面是实现自定义指令的代码:

import Vue from 'vue';

Vue.directive('right-click-menu', {
  bind(el, binding, vnode) {
    const groups = binding.value;
    let menu, menuShow;
    el.addEventListener('contextmenu', (event) => {
      event.preventDefault();

      if (!menu) {
        menu = vnode.context.$refs[`ctxmenu-${el.dataset.index}`][0];
        menuShow = false;
      }

      groups.forEach((group) => {
        vnode.context[group.key] = group.menus;
      });

      const { top, left } = event.currentTarget.getBoundingClientRect();

      menu.$el.style.top = `${top + event.currentTarget.clientHeight}px`;
      menu.$el.style.left = `${left}px`;

      menuShow = true;
    }, false);

    document.addEventListener('click', () => {
      if (menuShow) {
        menuShow = false;
        groups.forEach((group) => {
          vnode.context[group.key] = [];
        })
      }
    }, false)
  }
})

在上面代码中,我们通过Vue.directive方法定义了一个名为right-click-menu的指令。在使用该指令时,我们需要为它传递一个属性值(即菜单列表),例如:

<el-table-column
  v-right-click-menu="[{
    key: 'menu1',
    menus: [
      { text: '菜单1-1' },
      { text: '菜单1-2' }
    ]
  }]">
</el-table-column>

在指令绑定时,我们为目标元素(即el-table-column)绑定了contextmenu事件。当用户右键点击该元素时,菜单组件会出现在相应位置。当用户单击其他位置时,菜单组件会自动隐藏。

3. 使用菜单组件并调用自定义指令

最后一步是在el-table中使用菜单组件并调用自定义指令。具体代码如下:

<template>
  <el-table :data="tableData">
    <el-table-column type="index" label="序号"></el-table-column>
    <el-table-column prop="name" label="姓名"></el-table-column>
    <el-table-column prop="age" label="年龄" v-right-click-menu="[{
      key: 'menus',
      menus: [
        { text: '编辑' },
        { text: '删除' }
      ]
    }]"></el-table-column>
  </el-table>
  <right-click-menu ref="ctxmenu-{{index}}" :menus="menus" @menu-click="handleMenuClick"></right-click-menu>
</template>

<script>
import RightClickMenu from '@/components/RightClickMenu'
import '@/directives/right-click-menu'

export default {
  components: {
    RightClickMenu
  },
  data() {
    return {
      tableData: [
        { name: 'tom', age: 18 },
        { name: 'lily', age: 20 }
      ],
      menus: []
    }
  },
  methods: {
    handleMenuClick(index) {
      console.log(index);
    }
  }
}
</script>

在上面代码中,我们使用el-table-column组件定义了一个包含右键菜单的列。菜单的内容是一个数组,通过v-right-click-menu指令传递给了当前元素。

我们还使用了right-click-menu组件来定义菜单内容,并利用ref属性为每个菜单设置一个唯一标识。在data中定义了一个menus数组,用于存放当前活跃的菜单列表。

最后,通过监听menu-click事件,我们可以在父组件中处理菜单点击事件。

示例说明

示例1

假设我们有一个el-table,需要右键点击其中的每一行数据来展示菜单列表。

我们可以通过在template中添加菜单组件的代码,然后在自定义指令中为每一行数据绑定右键菜单实现该功能。

<template>
  <el-table :data="tableData">
    <el-table-column type="index" label="序号"></el-table-column>
    <el-table-column prop="name" label="姓名"></el-table-column>
    <el-table-column prop="age" label="年龄" v-right-click-menu="[{
      key: 'menus',
      menus: [
        { text: '编辑' },
        { text: '删除' }
      ]
    }]"></el-table-column>
  </el-table>
  <right-click-menu ref="ctxmenu-{{index}}" :menus="menus" @menu-click="handleMenuClick"></right-click-menu>
</template>

<script>
import RightClickMenu from '@/components/RightClickMenu'
import '@/directives/right-click-menu'

export default {
  components: {
    RightClickMenu
  },
  data() {
    return {
      tableData: [
        { name: 'tom', age: 18 },
        { name: 'lily', age: 20 }
      ],
      menus: []
    }
  },
  methods: {
    handleMenuClick(index) {
      console.log(index);
    }
  }
}
</script>

示例2

假设我们需要为el-table两列数据都添加右键菜单,但每一列的菜单列表都不相同。

我们可以在v-right-click-menu指令中传递一个包含两个元素的数组,每个元素都对应一个el-table-column列。元素的属性包括key(对应键名)和menus(对应菜单列表)。

<template>
  <el-table :data="tableData">
    <el-table-column type="index" label="序号"></el-table-column>
    <el-table-column prop="name" label="姓名" v-right-click-menu="[{
      key: 'menus1',
      menus: [
        { text: '编辑' },
        { text: '删除' }
      ]
    }]"></el-table-column>
    <el-table-column prop="age" label="年龄" v-right-click-menu="[{
      key: 'menus2',
      menus: [
        { text: '添加' },
        { text: '删除' }
      ]
    }]"></el-table-column>
  </el-table>
  <right-click-menu ref="ctxmenu-{{index}}-1" :menus="menus1" @menu-click="handleMenuClick"></right-click-menu>
  <right-click-menu ref="ctxmenu-{{index}}-2" :menus="menus2" @menu-click="handleMenuClick"></right-click-menu>
</template>

<script>
import RightClickMenu from '@/components/RightClickMenu'
import '@/directives/right-click-menu'

export default {
  components: {
    RightClickMenu
  },
  data() {
    return {
      tableData: [
        { name: 'tom', age: 18 },
        { name: 'lily', age: 20 }
      ],
      menus1: [],
      menus2: []
    }
  },
  methods: {
    handleMenuClick(index) {
      console.log(index);
    }
  }
}
</script>

以上就是“Vue el-table实现右键菜单功能”的详细攻略,希望对你有所帮助。

本文标题为:Vue el-table实现右键菜单功能