Vue中Table组件行内右键菜单实现方法(基于 vue + AntDesign)

下面是详细的讲解。

Vue中Table组件行内右键菜单实现方法(基于 vue + AntDesign)

在Vue项目中使用了AntDesign组件库的Table组件,在表格的某些字段需要可以快捷的执行一些操作,此时需要一种右键菜单来提供一些行内的操作选项。

前置条件

在本文中实现右键菜单的方法需满足以下条件:

  • Vue.js 2.x
  • AntDesign Vue UI 组件库
  • Uilts 工具库(本文中使用了Uilts工具库的throttle函数)

实现步骤

1. 定义右键菜单组件

在项目中定义一个右键菜单组件ContextMenu,此组件用来渲染右键菜单的内容。

<template>
  <a-dropdown @visibleChange="menuVisibleChange" :visible="visible">
    <a-menu slot="overlay" @click="handleClick">
      <a-menu-item v-for="(menu, index) in menus" :key="index">
        {{ menu.title }}
      </a-menu-item>
    </a-menu>
    <a>更多 <a-icon type="down" /></a>
  </a-dropdown>
</template>

<script>
export default {
  props: {
    visible: {
      type: Boolean,
      default: false
    },
    menus: {
      type: Array,
      default() {
        return []
      }
    }
  },
  methods: {
    handleClick(e) {
      const { key } = e.item
      const menu = this.menus.find(menu => menu.title === key)

      if (menu && menu.onClick instanceof Function) {
        menu.onClick()
      }
    },
    menuVisibleChange(visible) {
      if (!visible && this.menus.length) {
        this.$emit('close')
      }
    }
  }
}
</script>

ContextMenu组件中包含了一个Antd的下拉菜单组件a-dropdown,在a-dropdown组件上绑定了visibleChange事件和visible属性,visible属性用来控制右键菜单的显示,visibleChange事件用来响应右键菜单的显示和隐藏。ContextMenu组件还包含a-menu和a-menu-item组件,用来渲染右键菜单的内容。

ContextMenu组件定义了两个方法:handleClick和menuVisibleChange。

handleClick方法主要用来响应右键菜单的点击事件,获取到用户在菜单中点击的选项,并调用相应的回调函数。menuVisibleChange方法主要用来监听右键菜单的显示和隐藏,如果菜单隐藏了,就使用$emit方法向父组件传递消息。

在项目中可以通过对ContextMenu组件的visible属性进行控制,来制定右键菜单何时显示,如下:

<context-menu
  :menus="menuItems"
  :visible="menuVisible"
  @close="onMenuClose"
/>

2. 定义可右键菜单的行组件

在AntDesign的Table组件中,可以通过设置scopedSlots属性来自定义每列的渲染方式,其中的参数是一个对象,可以通过这个对象的row属性来访问到当前行对应的数据源。

在这个参数对象上增加一个属性contextMenu,设置为一个函数,返回一个渲染右键菜单的组件。

以下是一个简单的可右键菜单的行组件的示例。

<template>
  <div @contextmenu.stop.prevent="onRowContextMenu">
    <slot :row="row" :index="index" />
    <context-menu
      :menus="menus"
      :visible="menuVisible"
      @close="onMenuClose"
    />
  </div>
</template>

<script>
import ContextMenu from './ContextMenu.vue'

export default {
  components: {
    ContextMenu
  },
  props: {
    row: {
      type: Object,
      default() {
        return {}
      }
    },
    index: {
      type: Number,
      default: 0
    },
    menus: {
      type: Array,
      default() {
        return []
      }
    }
  },
  data() {
    return {
      menuVisible: false
    }
  },
  methods: {
    onRowContextMenu(e) {
      e.preventDefault()

      this.menuVisible = true
      this.showMenu(e.clientX, e.clientY)
    },
    showMenu(x, y) {
      const scrollY = window.scrollY || window.pageYOffset
      const scrollX = window.scrollX || window.pageXOffset

      this.$nextTick(() => {
        this.$refs.menu.$el.style.top = `${y - scrollY}px`
        this.$refs.menu.$el.style.left = `${x - scrollX}px`
      })
    },
    onMenuClose() {
      this.menuVisible = false
    }
  }
}
</script>

在可右键菜单的行组件定义了一个onRowContextMenu方法,此方法用来响应行的右键菜单事件。在这个方法中,调用showMenu方法,计算出右键菜单的坐标,并显示右键菜单。

右键菜单的显示需要用到showMenu方法来计算右键菜单的应该显示的位置,如下是showMenu方法的实现:

showMenu(x, y) {
  const scrollY = window.scrollY || window.pageYOffset
  const scrollX = window.scrollX || window.pageXOffset

  this.$nextTick(() => {
    this.$refs.menu.$el.style.top = `${y - scrollY}px`
    this.$refs.menu.$el.style.left = `${x - scrollX}px`
  })
}

通过获取到当前的鼠标坐标,使用window.scrollX和window.scrollY获取到页面的滚动距离,将它们计算到右键菜单显示的位置当中,确保右键菜单总是在鼠标位置下方显示即可。

3. 在Table组件上使用可右键菜单的行组件

对Table组件进行定义,使用之前定义好的可右键菜单的行组件,并且传入一个右键菜单的数据源menus。

<template>
  <a-table :columns="columns" :data-source="data">
    <template v-slot:customRender="slotProps">
      <menu-row
        :row="slotProps.row"
        :index="slotProps.$index"
        :menus="menus"
      >
        <template slot="name">{{ slotProps.row.name }}</template>
        <template slot="age">{{ slotProps.row.age }}</template>
        <template slot="operation">
          <a-button type="primary">操作</a-button>
        </template>
      </menu-row>
    </template>
  </a-table>
</template>

<script>
import MenuRow from './MenuRow.vue'

export default {
  components: {
    MenuRow
  },
  data() {
    return {
      menus: [
        {
          title: '删除',
          onClick() {
            console.log('delete')
          }
        },
        {
          title: '编辑',
          onClick() {
            console.log('edit')
          }
        }
      ],
      data: [
        {
          name: 'Tom',
          age: 26
        },
        {
          name: 'Jerry',
          age: 22
        }
      ],
      columns: [
        {
          title: '姓名',
          dataIndex: 'name',
          key: 'name',
          scopedSlots: { customRender: 'name' }
        },
        {
          title: '年龄',
          dataIndex: 'age',
          key: 'age',
          scopedSlots: { customRender: 'age' }
        },
        {
          title: '操作',
          key: 'operation',
          scopedSlots: { customRender: 'operation' }
        }
      ]
    }
  }
}
</script>

在这个示例中,使用了AntDesign提供的Table组件,并在其中使用了一个通过scopedSlots属性自定义渲染的组件MenuRow,最后依据传入的数据源menus来定义右键菜单的选项。

示例说明

  1. 在组件中使用防抖

在项目中,由于右键菜单的显示会在Table组件的每一行中产生,而这些行太多的话,就会在短时间内产生大量的右键菜单,从而导致应用的性能下降。为了避免这种情况的发生,可以使用Uilts库提供的throttle函数来对右键菜单的显示事件进行节流。

import { throttle } from '@utils'

export default {
  // ...
  methods: {
    onRowContextMenu: throttle(function (e) {
      e.preventDefault()

      this.menuVisible = true
      this.showMenu(e.clientX, e.clientY)
    }, 800)
    // ...
  }
}

在onRowContextMenu方法中使用了Uilts的throttle函数,将方法调用的节流时间设置为800ms。

  1. 在组件中使用props传递数据

在MenuRow组件和ContextMenu组件中,都使用props来进行参数传递,这种方式可以有效的减少代码耦合,并且使组件的复用更加容易。

<context-menu
  :menus="menuItems"
  :visible="menuVisible"
  @close="onMenuClose"
/>
<menu-row
  :row="slotProps.row"
  :index="slotProps.$index"
  :menus="menus"
>
  <!-- ... -->
</menu-row>

在这两个组件中,都有自己的props参数,并将一些数据通过props参数进行了传递。这种传递方式,让组件的复用和可维护性更高,同时也让组件更易于测试。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Vue中Table组件行内右键菜单实现方法(基于 vue + AntDesign) - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • excel如何插入窗体单选框控件?excel中窗体控件单选框的使用技巧

    Excel如何插入窗体单选框控件 首先,打开Excel文档,选中要插入单选框控件的单元格,然后在“开发工具”栏中点击“插入”下拉菜单,选择“表单控件”中的“单选框”即可插入单选框控件。 点击插入的单选框控件,可以看到控件属性栏,可以设置单选框的名称、值、颜色等属性,这些属性都可以根据需要进行设置。 在单选框控件的右侧,写下对应选项的文本。这样,当用户在单选框…

    other 2023年6月27日
    00
  • D3.js学习笔记—— 使用SVG坐标空间

    D3.js学习笔记——使用SVG坐标空间 D3.js是一个基于数据驱动的JavaScript库,用于创建动态、交互式的数据可视化。在D3.js中,我们可以使用SVG坐标空间来创建各种形状和图形。本文将详细介绍如何使用SVG坐标空间,并提供两个示例说明。 SVG坐标空间 SVG坐标空间是一个二维坐标系,用于描述SVG图形的位置和大小。在SVG坐标空间中,原点位…

    other 2023年5月5日
    00
  • C++可变参数模板深入深剖

    C++可变参数模板深入深剖 本文将深入探讨C++可变参数模板的相关知识,包括可变参数模板的定义、使用、实现和注意事项等内容。 定义可变参数模板 C++11引入了可变参数模板,可以像函数模板一样定义、使用可变数量的参数。其基本语法格式为: template <typename… Args> void foo(Args… args) { //…

    other 2023年6月27日
    00
  • 对ubuntu操作系统进行彻底优化

    对Ubuntu操作系统进行彻底优化 Ubuntu是一个备受欢迎的Linux操作系统,拥有超过2500万用户。但是默认安装的Ubuntu系统可能不是最适合每个用户的,因此,在本文中,我们将提供一些有用的技巧,以对Ubuntu系统进行彻底优化。 一、更新Ubuntu系统 首先,确保你的Ubuntu系统已经更新到最新版本。终端中可以使用以下命令进行更新: sudo…

    其他 2023年3月29日
    00
  • 常见网页编辑器(富文本 markdown 代码编辑等)

    以下是关于常见网页编辑器(富文本、Markdown、代码编辑等)的完整攻略,包括定义、使用方法、示例说明和注意事项。 定义 常见网页编辑器是用于创建和编辑网页的工具。它们可以分为三类:富文本编辑器、Markdown编辑器和代码编辑器。富文本编辑器提供了类似于Microsoft Word的界面,可以通过拖放、复制和粘贴等方式创建和编辑网页内容。Markdown…

    other 2023年5月8日
    00
  • centOS下yum安装配置samba

    CentOS下yum安装配置samba Samba是一项实现了Windows和Linux/Unix之间文件和打印机共享的服务。如果你有Linux和Windows机器在同一局域网内,那么在CentOS上安装和配置Samba是非常有用的,可以方便地在Windows上访问Linux文件。 1. 安装Samba 使用 yum 命令直接在CentOS系统中安装Samb…

    其他 2023年3月28日
    00
  • Java字节缓存流的构造方法之文件IO流

    Java字节缓存流的构造方法之文件IO流攻略 Java字节缓存流是一种用于处理字节数据的流,它提供了缓存功能,可以提高IO操作的效率。其中,文件IO流是字节缓存流的一种常见用法,用于读取和写入文件。 构造方法 Java字节缓存流的构造方法之文件IO流有以下两种: FileInputStream构造方法:用于创建一个字节缓存输入流,从文件中读取数据。 java…

    other 2023年8月6日
    00
  • Android代码块执行顺序分析总结

    下面详细讲述一下“Android代码块执行顺序分析总结”的攻略: 1. 概述 首先,代码块是指在类中而不是方法中定义的,它们用于进行一些初始化操作。 Android中的代码块主要分为两种:静态代码块和实例代码块。 静态代码块是指使用 static 修饰的代码块,一般用于执行一些静态变量的初始化操作;实例代码块是指不使用 static 修饰的代码块,一般用于执…

    other 2023年6月26日
    00
合作推广
合作推广
分享本页
返回顶部