Vue 3 中实现 Element Plus 表格的多选功能与条件操作(附Demo)

前言

本文主要以Demo的形式展示,展示要点为主

基本的vue3知识可通过查阅此专栏

基本知识点

  1. 数据绑定
    v-model 用于双向绑定数据,el-table 的 :data 属性用于绑定表格数据

  2. 选择框列
    使用 el-table-column 的 type=“selection” 属性来创建多选框列

  3. 处理选择变化
    @selection-change 事件用于处理选择状态变化,获取选中的数据

  4. 过滤和操作
    通过对选中的数据进行过滤和处理,实现不同的操作需求

1. Demo

多选按钮通常用于选择表格中的多行数据

常用的 UI 框架如 Element Plus 提供了易于集成的多选功能

<template>
  <el-table
    v-loading="loading"
    :data="tableData"
    :stripe="true"
    :show-overflow-tooltip="true"
    @selection-change="handleSelectionChange"
  >
    <el-table-column type="selection" width="55" />
    <el-table-column label="名称" prop="name" />
    <el-table-column label="状态" prop="status" />
    <el-table-column label="操作" fixed="right" width="200">
      <template #default="scope">
        <el-button @click="viewDetails(scope.row)">查看详情</el-button>
      </template>
    </el-table-column>
  </el-table>
  <el-button @click="handleBatchAction">执行批量操作</el-button>
</template>

其js如下:

<script setup>
import { ref } from 'vue';
import { ElTable, ElTableColumn, ElButton, ElMessage } from 'element-plus';

const loading = ref(false);
const tableData = ref([
  { id: 1, name: 'Item 1', status: '未提交' },
  { id: 2, name: 'Item 2', status: '已提交' },
  // ...更多数据
]);

const selectedRows = ref([]);

const handleSelectionChange = (selection) => {
  selectedRows.value = selection;
};

const viewDetails = (row) => {
  // 显示详情
  console.log('查看详情:', row);
};

const handleBatchAction = () => {
  if (selectedRows.value.length === 0) {
    ElMessage.warning('请选择要操作的项');
    return;
  }

  if (selectedRows.value.some(row => row.status !== '未提交')) {
    ElMessage.warning('只能对“未提交”状态的记录进行操作');
    return;
  }

  // 执行批量操作
  console.log('批量操作:', selectedRows.value);
};
</script>
  • 表格组件:el-table 组件用于展示数据,type=“selection” 创建多选框列
  • handleSelectionChange:处理选中项的变化,将选中的数据存储在 selectedRows 中
  • viewDetails:用于查看单条记录的详细信息
  • handleBatchAction:处理批量操作的逻辑,包括检查选中项的状态是否符合条件(如状态为“未提交”),然后执行操作

2. 实战

以上主要为了展示Demo的基本要点

对于实战也同理

增加选项按钮以及按钮触发

在这里插入图片描述

通过按钮的选中收集相关信息

在这里插入图片描述

将列表的id以数组的形式传输给后端
(上面我多收集了一个status,不满足的status可以在此处做过滤,让其不会触发按钮框并且有提示)

在这里插入图片描述

结果如下:

在这里插入图片描述

基于上述的Demo以及实战

通过按钮做一键删除 、修改等操作就很简单了


时隔半个月,又有批量删除的需求,对此再次进行复习

在这里插入图片描述

对应需要将所有的id传输到后端

原本前端单个删除按钮如下:

// 删除堆存计划
deleteGoodsStoragePlan: async (id: number) => {
  return await request.delete({ url: `/dangerous/goods-storage-plan/delete?id=` + id })
},

仿照其传输的方式:

deleteAllGoodsStoragePlan: async (data) => {
  // 以数组的形式传输给后端
  const idsString = data.join(',');
  return await request.post({ url: `/dangerous/goods-storage-plan/deleteAll`, 
    params: {
      ids: idsString
    }
  })
},

由于自身用的是Java相关代码,此处也放出相应的逻辑

@DeleteMapping("/delete")
@Operation(summary = "删除堆存计划")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('dangerous:goods-storage-plan:delete')")
public CommonResult<Boolean> deleteGoodsStoragePlan(@RequestParam("id") Long id) {
    goodsStoragePlanService.deleteGoodsStoragePlan(id);
    return success(true);
}

@PostMapping("/deleteAll")
@Operation(summary = "删除堆存计划")
@Parameter(name = "ids", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('dangerous:goods-storage-plan:deleteAll')")
public CommonResult<Boolean> deleteAllGoodsStoragePlan(@RequestParam("ids") List<Long> ids) {
    goodsStoragePlanService.deleteAllGoodsStoragePlan(ids);
    return success(true);
}

注意看其中的区别,后续只需要调用单一的删除功能即可

好的,我们来一步步实现基于Vue3、TypeScript和Element Plus的表格分页查询配置。 1. 首先我们需要安装Vue3、Vue Router、Element Plus和Axios等依赖: ```bash npm install vue@next vue-router@4.0.0-beta.8 element-plus@next axios ``` 2. 在`main.ts`引入VueVueRouter、Element Plus和Axios: ```typescript import { createApp } from 'vue' import App from './App.vue' import router from './router' import ElementPlus from 'element-plus' import 'element-plus/lib/theme-chalk/index.css' import axios from 'axios' const app = createApp(App) app.use(router) app.use(ElementPlus) app.config.globalProperties.$axios = axios app.mount('#app') ``` 3. 在`src/components`目录下创建一个`Table.vue`组件,用来展示表格数据: ```html <template> <el-table :data="tableData"> <el-table-column v-for="column in columns" :key="column.prop" :prop="column.prop" :label="column.label"></el-table-column> </el-table> </template> <script lang="ts"> import { defineComponent } from 'vue' export default defineComponent({ props: { columns: { type: Array, default: () => [] }, data: { type: Array, default: () => [] } }, computed: { tableData() { return this.data.map(item => { const row = {} this.columns.forEach(column => { row[column.prop] = item[column.prop] }) return row }) } } }) </script> ``` 4. 在`src/components`目录下创建一个`Pagination.vue`组件,用来展示分页控件: ```html <template> <el-pagination :current-page="currentPage" :page-size="pageSize" :total="total" @current-change="handleCurrentChange" @size-change="handleSizeChange" ></el-pagination> </template> <script lang="ts"> import { defineComponent } from 'vue' export default defineComponent({ props: { currentPage: { type: Number, default: 1 }, pageSize: { type: Number, default: 10 }, total: { type: Number, default: 0 } }, methods: { handleCurrentChange(currentPage: number) { this.$emit('update:currentPage', currentPage) }, handleSizeChange(pageSize: number) { this.$emit('update:pageSize', pageSize) } } }) </script> ``` 5. 在`src/views`目录下创建一个`TableDemo.vue`视图组件,用来展示表格和分页控件: ```html <template> <div> <el-form :inline="true" :model="query" class="table-demo__form"> <el-form-item v-for="field in fields" :key="field.prop" :label="field.label"> <el-input v-model="query[field.prop]" placeholder="请输入"></el-input> </el-form-item> <el-button type="primary" icon="el-icon-search" @click="handleSearch">查询</el-button> </el-form> <Table :columns="columns" :data="data"></Table> <Pagination :currentPage.sync="currentPage" :pageSize.sync="pageSize" :total="total"></Pagination> </div> </template> <script lang="ts"> import { defineComponent, ref } from 'vue' import axios from 'axios' import Table from '@/components/Table.vue' import Pagination from '@/components/Pagination.vue' export default defineComponent({ components: { Table, Pagination }, setup() { const fields = [ { prop: 'name', label: '姓名' }, { prop: 'age', label: '年龄' }, { prop: 'gender', label: '性别' } ] const columns = [ { prop: 'name', label: '姓名' }, { prop: 'age', label: '年龄' }, { prop: 'gender', label: '性别' } ] const currentPage = ref(1) const pageSize = ref(10) const total = ref(0) const data = ref([]) const query = ref({ name: '', age: '', gender: '' }) const fetchData = async () => { const res = await axios.get('/api/users', { params: { ...query.value, page: currentPage.value, size: pageSize.value } }) data.value = res.data.items total.value = res.data.total } const handleSearch = () => { currentPage.value = 1 fetchData() } fetchData() return { fields, columns, currentPage, pageSize, total, data, query, handleSearch } } }) </script> <style> .table-demo__form { margin-bottom: 20px; } </style> ``` 6. 在`src/router/index.ts`配置路由: ```typescript import { createRouter, createWebHashHistory } from 'vue-router' import TableDemo from '@/views/TableDemo.vue' const routes = [ { path: '/', name: 'TableDemo', component: TableDemo } ] const router = createRouter({ history: createWebHashHistory(), routes }) export default router ``` 7. 在`public`目录下创建一个`api`目录,用来模拟后端接口: ```json // api/users.json { "total": 100, "items": [ { "name": "张三", "age": 18, "gender": "男" }, { "name": "李四", "age": 20, "gender": "女" }, { "name": "王五", "age": 22, "gender": "男" }, { "name": "赵六", "age": 24, "gender": "女" }, { "name": "钱七", "age": 26, "gender": "男" } ] } ``` 8. 在`package.json`添加一个`dev`命令,用来启动开发服务器: ```json { "scripts": { "dev": "vite" } } ``` 9. 启动开发服务器并访问`http://localhost:3000/`,就可以看到我们的表格和分页控件了。 以上就是基于Vue3、TypeScript和Element Plus的表格分页查询配置的实现步骤。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农研究僧

你的鼓励将是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值