vue3中基于element-plus封装一个表格弹框组件,要求可以单选和多选table数据

news2024/11/17 18:26:18

单选:
在这里插入图片描述

<template>
  <SelectMaterial
      ref="selectMaterialRef"
      check="checkbox"
      @select="selectMaterial"
    ></SelectMaterial>
   <el-button type="primary" size="small" icon="el-icon-plus" @click="handleAddMaterial"
     >添加备件</el-button>
</template>
<script setup>
import { ref } from 'vue';

const selectMaterialRef = ref('');
// 选择事件
const selectMaterial = data => {
  console.log('选择的表格数据', data);
};
// 打开添加备件弹框
const handleAddMaterial = () => {
  selectMaterialRef.value.openDialog();
};
</script>

在这里插入图片描述

多选:
在这里插入图片描述

<template>
  <SelectMaterial
      ref="selectMaterialRef"
      check="checkbox"
      @select="selectMaterial"
    ></SelectMaterial>
   <el-button type="primary" size="small" icon="el-icon-plus" @click="handleAddMaterial"
     >添加备件</el-button>
</template>
<script setup>
import { ref } from 'vue';

const selectMaterialRef = ref('');
// 选择事件
const selectMaterial = data => {
  console.log('选择的表格数据', data);
};
// 打开添加备件弹框
const handleAddMaterial = () => {
  selectMaterialRef.value.openDialog();
};
</script>

在这里插入图片描述

弹框表格组件代码

<template>
  <el-dialog v-model="dialogShow" @close="handleClose" width="50%" title="选择备件">
    <el-table
      border
      ref="tableRef"
      :data="tableData"
      :row-key="row => row.id"
      :header-cell-style="{ textAlign: 'center', backgroundColor: '#f3f3f3' }"
      :cell-style="{ textAlign: 'center' }"
      @selection-change="handleSelectionChange"
      style="height: 352px; overflow: auto; margin: 10px 0"
      size="small"
    >
      <el-table-column v-if="check === 'checkbox'" type="selection"></el-table-column>
      <el-table-column v-else-if="check === 'radio'" width="50">
        <template #default="scope">
          <el-radio v-model="selectedRow" :value="scope.row.id"></el-radio>
        </template>
      </el-table-column>
      <el-table-column type="index" width="80" label="序号">
        <template #default="{ $index }">
          {{ (currentPage - 1) * pageSize + $index + 1 }}
        </template>
      </el-table-column>
      <el-table-column prop="partNumber" label="备件编号"></el-table-column>
      <el-table-column prop="partName" label="备件名称"></el-table-column>
      <el-table-column prop="specification" label="规格型号"></el-table-column>
      <el-table-column prop="manufacturer" label="生产厂家"></el-table-column>
      <el-table-column prop="unit" label="单位"></el-table-column>
    </el-table>
    <div style="display: flex; justify-content: flex-end; margin-top: 10px">
      <el-pagination
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="currentPage"
        :page-sizes="[10, 20, 30, 40]"
        :page-size="pageSize"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total"
        small
      >
      </el-pagination>
    </div>
    <div style="text-align: center; margin-top: 20px">
      <el-button size="small" @click="handleClose" style="margin-right: 30px;">取消</el-button>
      <el-button size="small" type="primary" @click="handleSelect">选择</el-button>
    </div>
  </el-dialog>
</template>

<script name="select-material-dialog" setup>
import { ref } from 'vue';

// 对话框是否可见
const dialogShow = ref(false);
// 多选选中的行
const selectedRows = ref([]);
// 单选选中的行
const selectedRow = ref(null);
// 当前页码
const currentPage = ref(1);
// 每页显示的条数
const pageSize = ref(10);
// 总条数
const total = ref(0);
// 表格数据
const tableData = ref([]);
// 表格ref
const tableRef = ref(null);

// 定义属性
const props = defineProps({
  // 选择模式,可以是 'radio' 或 'checkbox'
  check: {
    type: String,
    default: 'checkbox',
  },
});

// 定义事件
const $emit = defineEmits(['select']);

// 获取数据的方法
const fetchData = async () => {
  // 模拟接口请求,这里使用 setTimeout 来模拟异步操作
  await new Promise(resolve => setTimeout(resolve, 1000));

  // 更新数据
  const data = Array.from({ length: pageSize.value }, (_, i) => ({
    id: (currentPage.value - 1) * pageSize.value + i + 1, // 注意这里的 +1,因为 id 应该从 1 开始,而不是从 0 开始
    partNumber: `编号${(currentPage.value - 1) * pageSize.value + i + 1}`, // 同样,编号也应该从 1 开始
    partName: `名称${i}`,
    specification: `规格${i}`,
    manufacturer: `厂家${i}`,
    unit: `单位${i}`,
  }));
  tableData.value = data;
  total.value = 100; // 假设总条数为 100
};

// 切换对话框的可见状态
const openDialog = () => {
  dialogShow.value = true;
};

// 关闭对话框
const handleClose = () => {
  dialogShow.value = false;
};

// 处理分页器当前页改变
const handleCurrentChange = async val => {
  console.log('current', val);
  currentPage.value = val;
  await fetchData();
};

// 处理选项变化
const handleSelectionChange = val => {
  selectedRows.value = val;
};

// 处理每页显示的条数改变
const handleSizeChange = async val => {
  pageSize.value = val;
  await fetchData();
};

// 处理选择按钮点击
const handleSelect = () => {
  if (props.check === 'radio') {
    const selectedData = tableData.value.find(row => row.id === selectedRow.value);
    $emit('select', selectedData);
  } else {
    $emit('select', selectedRows.value);
  }
  handleClose();
};

// 暴露方法和属性
defineExpose({ openDialog });
// 初始获取数据
fetchData();
</script>

这里多啰嗦一句单选,我这里是自定义列,使用单选框的方式实现的

<el-table-column v-else-if="check === 'radio'" width="50">
  <template #default="scope">
    <el-radio v-model="selectedRow" :label="scope.row.id"></el-radio>
  </template>
</el-table-column>
<script>
// 选中的行的数据
const selectedRow = ref(null);
// 处理选择按钮点击
const handleSelect = () => {
  if (props.check === 'radio') {
    const selectedData = tableData.value.find(row => row.id === selectedRow.value);
    $emit('select', selectedData);
  } 
};
</script>

为什么要这样呢,因为我开始是使用多选加反选的方式实现单选,但这样存在一个bug,就是多选框的表头有个全选按钮,点击那个全选的时候会出现反选的问题。

<template>
    <el-table
      ref="tableRef"
      :data="tableData"
      @selection-change="handleSelectionChange"
    >
      <el-table-column  type="selection"></el-table-column>
      ......
    </el-table>
</template>
<script>
const selectedRow = ref(null);
const handleSelectionChange = (val: []) => {
  console.log(val);
  if (val.length > 1) {
  	// 单选
    tableRef.value!.toggleRowSelection(val[0], val[val.length - 1]);
    selectedRow .value = [val[val.length - 1]];
  } else {
    // 多选
    selectedRow .value = val;
  }
}
</script>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1697589.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【STM32】新建工程(江科大)

文章目录 STM32的开发方式库函数文件夹一、新建一个基于标准库的工程1.建立一个存放工程的文件夹2.打开Keil5 二、通过配置寄存器来完成点灯1.配置RCC寄存器2.配置PC13口&#xff08;1&#xff09;配置PC13口的模式&#xff08;2&#xff09;给PC13口输出数据 三、为寄存器添加…

与MySQL的初相遇

&#x1f30e;初识MySQL 注&#xff1a;本文SQL语句只为了验证猜想&#xff0c;不会也不要紧。 文章目录&#xff1a; MySql开端 认识数据库       什么是数据库       主流数据库       MySQL的本质 MySQL基础使用       连接mysql服务器     …

【Linux初探】:解锁开源世界的神秘钥匙

文章目录 &#x1f680;一、了解Linux&#x1f525;二、Linux 的发行版❤️三、Linux应用领域&#x1f4a5;四、Linux vs Windows & mac &#x1f680;一、了解Linux Linux是一种自由、开放源代码的操作系统&#xff0c;它的内核由芬兰计算机科学家Linus Torvalds在1991年创…

图片AI高效生成惊艳之作,一键解锁无限创意,轻松打造概念艺术新纪元!

在数字化时代&#xff0c;图片已经成为我们表达创意、传递信息的重要载体。然而&#xff0c;传统的图片生成方式往往耗时耗力&#xff0c;无法满足我们对于高效、创意的需求。幸运的是&#xff0c;现在有了图片AI&#xff0c;它以其高效、智能的特点&#xff0c;为我们带来了全…

数组-最接近给出数字的三数之和

题目描述 解题思路 这里使用三层for循环&#xff0c;暴力解法穷举所有三个数和的可能性&#xff0c;注意三层循环里的索引不要重复。 代码实现 import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返…

C语言——小知识和小细节19

一、奇数位与偶数位互换 1、题目介绍 实现一个宏&#xff0c;将一个整数的二进制补码的奇数位与偶数位互换。输出格式依旧是十进制整数。示例&#xff1a; 2、分析 既然想要交换奇数位和偶数位上的数字&#xff0c;那么我们就要先得到奇数位和偶数位上的数字&#xff0c;那么…

THREE.JS中的向量点乘,以及他的几何意义。

1. THREE.JS中的向量点乘&#xff0c;以及他的几何意义 向量点乘的公式 : 2. 在three.js 中计算向量点乘 const a new THREE.Vector3(10, 10, 0); const b new THREE.Vector3(20, 0, 0); const dot a.dot(b);从这里可以看出&#xff0c;向量的点乘的结果是一个数字(标量…

嵌入式进阶——LED呼吸灯(PWM)

&#x1f3ac; 秋野酱&#xff1a;《个人主页》 &#x1f525; 个人专栏:《Java专栏》《Python专栏》 ⛺️心若有所向往,何惧道阻且长 文章目录 PWM基础概念STC8H芯片PWMA应用PWM配置详解占空比 PWM基础概念 PWM全称是脉宽调制&#xff08;Pulse Width Modulation&#xff09…

安卓手机电脑平板均支持

最近随着人工智能的火热&#xff0c;越来越多人问我怎么设置&#xff0c;我这边主要提供简单的配置&#xff0c;能够实现想要的功能&#xff0c;不懂得的友友们可以私聊我&#xff0c;

一文读懂Apollo客户端配置加载流程

本文基于 apollo-client 2.1.0 版本源码进行分析 Apollo 是携程开源的配置中心&#xff0c;能够集中化管理应用不同环境、不同集群的配置&#xff0c;配置修改后能够实时推送到应用端&#xff0c;并且具备规范的权限、流程治理等特性。 Apollo支持4个维度管理Key-Value格式的配…

MyBatis详细教程!!(入门版)

目录 什么是MyBatis&#xff1f; MyBatis入门 1&#xff09;创建工程 2&#xff09;数据准备 3&#xff09;配置数据库连接字符串 4&#xff09;写持久层代码 5&#xff09;生成测试类 MyBatis打印日志 传递参数 MyBatis的增、删、改 增&#xff08;Insert&#xff0…

OpenAI策略:指令层级系统让大模型免于恶意攻击

现代的大模型&#xff08;LLMs&#xff09;不再仅仅是简单的自动完成系统&#xff0c;它们有潜力赋能各种代理应用&#xff0c;如网页代理、电子邮件秘书、虚拟助手等。然而&#xff0c;这些应用广泛部署的一个主要风险是敌手可能诱使模型执行不安全或灾难性的行动&#xff0c;…

别人不愿意教,那我来教你Simulink建模(二)【语法知识】【原创分享】

文章目录 前言节点和状态的区别?local 和非 local 的区别?事件的作用?Bus 总线?Memory 模块?caller用法?自己瞎练习的(我也不知道为啥会多出来.h文件)自己瞎练习的(这个没有多出来.h文件)autosar实例学习前言 继续更新去年的博文系列,请君切记,师父领进门修行在个…

ant design pro 6.0列表渲实践demo

ant design pro 用户列表渲实践 用户页面&#xff1a; src\pages\Admin\User\index.tsx import { PlusOutlined } from ant-design/icons; import type { ActionType, ProColumns, ProDescriptionsItemProps } from ant-design/pro-components; import {PageContainer,ProDe…

JAVA方法引用,异常,File,IO流知识总结

文章目录 JAVA第六周学习笔记方法引用引用静态方法引用成员方法引用构造方法其他调用方式使用类名引用成员方法引用数组的构造方法 异常作用处理方式常见成员方法抛出异常finally自定义异常 File路径构造方法**判断、获取****创建 、删除****获取并遍历**练习 IO流体系字节流Fi…

软件设计师备考笔记(十):网络与信息安全基础知识

文章目录 一、网络概述二、网络互连硬件&#xff08;一&#xff09;网络的设备&#xff08;二&#xff09;网络的传输介质&#xff08;三&#xff09;组建网络 三、网络协议与标准&#xff08;一&#xff09;网络的标准与协议&#xff08;二&#xff09;TCP/IP协议簇 四、Inter…

Linux基础(八):计算机基础概论

本篇博客简单介绍计算机的基础知识&#xff0c;为后续学习做个铺垫。 目录 一、计算机的基本组成 1.1 计算机组成五大部件 1.1.1 运算器&#xff08;Arithmetic Logic Unit&#xff0c;ALU&#xff09; 1.1.2控制器 &#xff08;Control Unit&#xff0c;CU&#xff09; …

详解 Cookies 和 WebStorage

Cookies 和 WebStorage Cookies 和 WebStorageCookies简要介绍操作 Cookies&#xff08;document.cookie&#xff09;不足之处 WebStorage简要介绍LocalStorage Vs. SessionStorage操作 WebStorage 三种数据存储方式的对比分析共性差异 REFERENCES Cookies 和 WebStorage Cook…

某钢铁企业数字化转型规划案例(114页PPT)

案例介绍&#xff1a; 该钢铁企业的数字化转型案例表明&#xff0c;数字化转型是钢铁企业应对市场竞争、提高生产效率、降低成本、优化资源配置和降低能耗排放的重要手段。通过引入先进的技术和管理理念&#xff0c;加强员工培训和人才引进&#xff0c;企业可以成功实现数字化…

【Java】欸...?我学集合框架?真的假的?

【Java】欸…&#xff1f;我学集合框架&#xff1f;真的假的&#xff1f; Java集合框架 概述 Java集合框架主要由以下几个部分组成&#xff1a; 接口&#xff08;Interfaces&#xff09;&#xff1a;定义了集合的基本操作&#xff0c;如添加、删除、遍历等。实现&#xff0…