当前位置: 首页 > news >正文

Vue的高级表格组件库【vxe-table】

文章目录

  • 前言
  • vxe-table
  • 官网
  • 实现表头拖拽
  • 树形表格
  • 全键盘操作
  • 后言

前言

hello world欢迎来到前端的新世界


😜当前文章系列专栏:前端系列文章
🐱‍👓博主在前端领域还有很多知识和技术需要掌握,正在不断努力填补技术短板。(如果出现错误,感谢大家指出)🌹
💖感谢大家支持!您的观看就是作者创作的动力

vxe-table

一款专门用来对Vue3表格进行复杂操作的ui组件库,虚拟滚动,普通表格的行拖拽,表格的全屏展示,表格的全键盘操作,禁用编辑等。

官网

官网地址

下载

npm install xe-utils vxe-table

配置在main.js或者main.ts里面

import { App, createApp } from 'vue'
import VXETable from 'vxe-table'
import 'vxe-table/lib/style.css'function useTable (app: App) {app.use(VXETable)
}createApp(App).use(useTable).mount('#app')

实现表头拖拽

直接复制

<template><div><vxe-grid v-bind="gridOptions"><template #toolbar_buttons><vxe-button @click="gridOptions.align = 'left'">居左</vxe-button><vxe-button @click="gridOptions.align = 'center'">居中</vxe-button><vxe-button @click="gridOptions.align = 'right'">居右</vxe-button></template></vxe-grid></div>
</template><script lang="ts" setup>
import { reactive } from 'vue'
import { VxeGridProps } from 'vxe-table'interface RowVO {id: numbername: stringnickname: stringrole: stringsex: stringage: numberaddress: string
}const gridOptions = reactive<VxeGridProps<RowVO>>({border: true,height: 300,align: null,columnConfig: {resizable: true},columns: [{ type: 'seq', width: 50 },{ field: 'name', title: 'name' },{ field: 'sex', title: 'sex' },{ field: 'address', title: 'Address' }],toolbarConfig: {slots: {buttons: 'toolbar_buttons'}},data: [{ id: 10001, name: 'Test1', nickname: 'T1', role: 'Develop', sex: 'Man', age: 28, address: 'Shenzhen' },{ id: 10002, name: 'Test2', nickname: 'T2', role: 'Test', sex: 'Women', age: 22, address: 'Guangzhou' },{ id: 10003, name: 'Test3', nickname: 'T3', role: 'PM', sex: 'Man', age: 32, address: 'Shanghai' },{ id: 10004, name: 'Test4', nickname: 'T4', role: 'Designer', sex: 'Women', age: 23, address: 'Shenzhen' },{ id: 10005, name: 'Test5', nickname: 'T5', role: 'Develop', sex: 'Women', age: 30, address: 'Shanghai' },{ id: 10006, name: 'Test6', nickname: 'T6', role: 'Designer', sex: 'Women', age: 21, address: 'Shenzhen' },{ id: 10007, name: 'Test7', nickname: 'T7', role: 'Test', sex: 'Man', age: 29, address: 'Shenzhen' },{ id: 10008, name: 'Test8', nickname: 'T8', role: 'Develop', sex: 'Man', age: 35, address: 'Shenzhen' }]
})
</script>

树形表格

<template><div><vxe-toolbar><template #buttons><vxe-button @click="expandAllEvent">展开所有</vxe-button><vxe-button @click="claseExpandEvent">收起所有</vxe-button></template></vxe-toolbar><vxe-tableshow-overflowheight="400"ref="tableRef":loading="loading":tree-config="{transform: true}":scroll-y="{enabled: true, gt: 20}":data="tableData"><vxe-column type="seq" width="200" tree-node></vxe-column><vxe-column field="id" title="Id"></vxe-column><vxe-column field="name" title="Name"></vxe-column></vxe-table></div>
</template><script lang="ts" setup>
import { ref } from 'vue'
import { VxeTableInstance } from 'vxe-table'interface RowVO {id: numberparentId: number | nullname: string
}const tableRef = ref<VxeTableInstance<RowVO>>()const loading = ref(false)
const tableData = ref<RowVO[]>([])const loadList = () => {loading.value = truefetch('/resource/json/provinces_list.json').then(res => res.json()).then((data: RowVO[]) => {tableData.value = dataloading.value = false})
}const expandAllEvent = () => {const $table = tableRef.valueif ($table) {$table.setAllTreeExpand(true)}
}const claseExpandEvent = () => {const $table = tableRef.valueif ($table) {$table.clearTreeExpand()}
}loadList()
</script>

全键盘操作

template

<vxe-toolbar :refresh="{query: findList}"><template #buttons><vxe-button><template #default>新增操作</template><template #dropdowns><vxe-button type="text" @click="insertEvent(null)">从第一行插入</vxe-button><vxe-button type="text" @click="insertEvent(-1)">从最后插入</vxe-button><vxe-button type="text" @click="insertEvent($refs.xTable.getData(100))">插入到 100</vxe-button><vxe-button type="text" @click="insertEvent($refs.xTable.getData(400))">插入到 400</vxe-button></template></vxe-button><vxe-button><template #default>删除操作</template><template #dropdowns><vxe-button type="text" @click="$refs.xTable.removeCheckboxRow()">删除选中</vxe-button><vxe-button type="text" @click="$refs.xTable.remove($refs.xTable.getData(0))">删除第一行</vxe-button><vxe-button type="text" @click="$refs.xTable.remove($refs.xTable.getData($refs.xTable.getData().length - 1))">删除最后一行</vxe-button><vxe-button type="text" @click="$refs.xTable.remove($refs.xTable.getData(100))">删除第 100</vxe-button></template></vxe-button><vxe-button><template #default>校验操作</template><template #dropdowns><vxe-button type="text" @click="validEvent">快速校验</vxe-button><vxe-button type="text" @click="fullValidEvent">完整快速校验</vxe-button><vxe-button type="text" @click="selectValidEvent">选中行校验</vxe-button></template></vxe-button><vxe-button @click="getInsertEvent">获取新增</vxe-button><vxe-button @click="getRemoveEvent">获取删除</vxe-button><vxe-button @click="getUpdateEvent">获取修改</vxe-button><vxe-button><template #default>滚动操作</template><template #dropdowns><vxe-button type="text" @click="$refs.xTable.scrollToRow($refs.xTable.getData(10))">滚动到第 10</vxe-button><vxe-button type="text" @click="$refs.xTable.scrollToRow($refs.xTable.getData(400))">滚动第 400</vxe-button><vxe-button type="text" @click="$refs.xTable.scrollToColumn($refs.xTable.getColumns(1))">滚动第 1</vxe-button><vxe-button type="text" @click="$refs.xTable.scrollToColumn($refs.xTable.getColumns(10))">滚动第 10</vxe-button></template></vxe-button></template></vxe-toolbar><vxe-tablebordershow-overflowkeep-sourceref="xTable"height="300":column-config="{resizable: true}":loading="demo1.loading":edit-rules="demo1.validRules":mouse-config="{selected: true}":edit-config="{trigger: 'dblclick', mode: 'cell', showStatus: true}":keyboard-config="{isArrow: true, isDel: true, isEnter: true, isTab: true, isEdit: true}"><vxe-column type="checkbox" width="60"></vxe-column><vxe-column type="seq" width="100"></vxe-column><vxe-column field="name" title="Name" sortable width="200" :edit-render="{autofocus: '.vxe-input--inner'}"><template #edit="scope"><vxe-input v-model="scope.row.name" type="text" @change="$refs.xTable.updateStatus(scope)"></vxe-input></template></vxe-column><vxe-column field="age" title="Age" width="200" :edit-render="{autofocus: '.vxe-input--inner'}"><template #edit="scope"><vxe-input v-model="scope.row.age" type="text" @change="$refs.xTable.updateStatus(scope)"></vxe-input></template></vxe-column><vxe-column field="sex" title="Sex" width="200" :edit-render="{autofocus: '.vxe-input--inner'}"><template #edit="scope"><vxe-input v-model="scope.row.sex" type="text" @change="$refs.xTable.updateStatus(scope)"></vxe-input></template></vxe-column><vxe-column field="rate" title="Rate" width="200"></vxe-column><vxe-column field="region" title="Region" width="200"></vxe-column><vxe-column field="time" title="Time" width="200"></vxe-column><vxe-column field="address" title="Address" width="300" show-overflow></vxe-column><vxe-column field="updateTime" title="UpdateTime" width="200"></vxe-column><vxe-column field="createTime" title="CreateTime" width="200"></vxe-column></vxe-table>

script

import { defineComponent, reactive, ref } from 'vue'import { VXETable, VxeTableInstance, VxeTablePropTypes } from 'vxe-table'export default defineComponent({setup () {const xTable = ref<VxeTableInstance>()const demo1 = reactive({loading: false,validRules: {name: [{ required: true, message: 'app.body.valid.rName' },{ min: 3, max: 50, message: '名称长度在 3 到 50 个字符' }],sex: [{ required: true, message: '性别必须填写' }]} as VxeTablePropTypes.ValidConfig})const mockList = (size: number) => {const list: any[] = []for (let index = 0; index < size; index++) {list.push({checked: false,name: `名称${index}`,sex: '0',num: 123,age: 18,num2: 234,rate: 3,address: 'shenzhen'})}return list}const findList = () => {demo1.loading = truereturn new Promise(resolve => {setTimeout(() => {const tableData = mockList(600)// 阻断 vue 对大数组的监听,避免 vue 绑定大数据造成短暂的卡顿const $table = xTable.valueif ($table) {$table.loadData(tableData)}resolve(null)demo1.loading = false}, 300)})}const validEvent = async () => {const $table = xTable.valueconst errMap = await $table.validate()if (errMap) {VXETable.modal.message({ status: 'error', content: '校验不通过!' })} else {VXETable.modal.message({ status: 'success', content: '校验成功!' })}}const fullValidEvent = async () => {const $table = xTable.valueconst errMap = await $table.fullValidate()if (errMap) {const msgList: string[] = []Object.values(errMap).forEach((errList) => {errList.forEach(params => {const { rowIndex, column, rules } = paramsrules.forEach(rule => {msgList.push(`${rowIndex + 1}${column.title} 校验错误:${rule.message}`)})})})VXETable.modal.message({status: 'error',slots: {default () {return [<div class="red" style="max-height: 400px;overflow: auto;">{msgList.map(msg => {return <div>{ msg }</div>})}</div>]}}})} else {VXETable.modal.message({ status: 'success', content: '校验成功!' })}}const selectValidEvent = async () => {const $table = xTable.valueconst selectRecords = $table.getCheckboxRecords()if (selectRecords.length > 0) {const errMap = await $table.validate(selectRecords).catch(errMap => errMap)if (errMap) {VXETable.modal.message({ status: 'error', content: '校验不通过!' })} else {VXETable.modal.message({ status: 'success', content: '校验成功!' })}} else {VXETable.modal.message({ status: 'warning', content: '未选中数据!' })}}const insertEvent = (row: any) => {const $table = xTable.valueconst record = {checked: false}$table.insertAt(record, row).then(({ row }) => {$table.setEditRow(row)})}const getInsertEvent = () => {const $table = xTable.valueconst insertRecords = $table.getInsertRecords()VXETable.modal.alert(insertRecords.length)}const getRemoveEvent = () => {const $table = xTable.valueconst removeRecords = $table.getRemoveRecords()VXETable.modal.alert(removeRecords.length)}const getUpdateEvent = () => {const $table = xTable.valueconst updateRecords = $table.getUpdateRecords()VXETable.modal.alert(updateRecords.length)}findList()return {xTable,demo1,findList,validEvent,fullValidEvent,selectValidEvent,insertEvent,getInsertEvent,getRemoveEvent,getUpdateEvent}}})

后言

创作不易,要是本文章对广大读者有那么一点点帮助 不妨三连支持一下,您的鼓励就是博主创作的动力

相关文章:

Vue的高级表格组件库【vxe-table】

文章目录 前言vxe-table官网实现表头拖拽树形表格全键盘操作后言 前言 hello world欢迎来到前端的新世界 &#x1f61c;当前文章系列专栏&#xff1a;前端系列文章 &#x1f431;‍&#x1f453;博主在前端领域还有很多知识和技术需要掌握&#xff0c;正在不断努力填补技术短板…...

从0到0.01入门React | 002.精选 React 面试题

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…...

假冒 Skype 应用程序网络钓鱼分析

参考链接: https://slowmist.medium.com/fake-skype-app-phishing-analysis-35c1dc8bc515 背景 在Web3世界中&#xff0c;涉及假冒应用程序的网络钓鱼事件相当频繁。慢雾安全团队此前曾发表过分析此类网络钓鱼案例的文章。由于Google Play在中国无法访问&#xff0c;许多用户…...

软件外包开发的需求表达方法

软件开发需求的有效表达对于项目的成功至关重要。无论选择哪种需求表达方法&#xff0c;清晰、详细、易于理解是关键。与开发团队建立良好的沟通渠道&#xff0c;确保他们对需求有充分的理解&#xff0c;并随着项目的推进及时调整和更新需求文档。以下是一些常用的需求表达方法…...

详解JS的四种异步解决方案:回调函数、Promise、Generator、async/await

同步&异步的概念 在讲这四种异步方案之前&#xff0c;我们先来明确一下同步和异步的概念&#xff1a; 所谓同步(synchronization)&#xff0c;简单来说&#xff0c;就是顺序执行&#xff0c;指的是同一时间只能做一件事情&#xff0c;只有目前正在执行的事情做完之后&am…...

Python进行多线程爬取数据通用模板

首先&#xff0c;我们需要导入所需的库&#xff0c;包括requests和BeautifulSoup。requests库用于发送HTTP请求&#xff0c;BeautifulSoup库用于解析HTML文档。 import requests from bs4 import BeautifulSoup然后&#xff0c;我们需要定义一个函数来发送HTTP请求并返回响应。…...

基于springboot实现沁园健身房预约管理系统【项目源码】

基于springboot实现沁园健身房预约管理系统演示 B/S架构 B/S结构是目前使用最多的结构模式&#xff0c;它可以使得系统的开发更加的简单&#xff0c;好操作&#xff0c;而且还可以对其进行维护。使用该结构时只需要在计算机中安装数据库&#xff0c;和一些很常用的浏览器就可以…...

论文笔记:Deep Trajectory Recovery with Fine-Grained Calibration using Kalman Filter

TKDE 2021 1 intro 1.1 背景 用户轨迹数据对于改进以用户为中心的应用程序很有用 POI推荐城市规划路线规划由于设备和环境的限制&#xff0c;许多轨迹以低采样率记录 采样的轨迹无法详细说明物体的实际路线增加了轨迹中两个连续采样点之间的不确定性——>开发有效的算法以…...

ubuntu下tensorrt环境配置

文章目录 一、Ubuntu18.04环境配置1.1 安装工具链和opencv1.2 安装Nvidia相关库1.2.1 安装Nvidia显卡驱动1.2.2 安装 cuda11.31.2.3 安装 cudnn8.21.2.4 下载 tensorrt8.4.2.4 二、编写CMakeLists.txt三、TensorRT系列教程 一、Ubuntu18.04环境配置 教程同样适用与ubuntu22.04…...

网络安全基础之php开发文件下载的实现

前言 php是网络安全学习里必不可少的一环&#xff0c;简单理解php的开发环节能更好的帮助我们去学习php以及其他语言的web漏洞原理 正文 在正常的开发中&#xff0c;文件下载的功能是必不可少&#xff0c;比如我们在论坛看到好看图片好听的歌时&#xff0c;将其下载下来时就…...

【学习笔记】 - GIT的基本操作,IDEA接入GIT以及上传hub

用github蛮多&#xff0c;但git没怎么用&#xff0c;看着视频对着写点笔记以及操作 一、GIT文件的三种状态和模式 已提交(committed) 已提交表示数据已经安全的保存在本地数据库中。 已修改(modified) 已修改表示修改了文件&#xff0c;但还没保存到数据库中。…...

Antd React Form.Item内部是自定义组件怎么自定义返回值

在线演示https://stackblitz.com/edit/stackblitz-starters-xwtwyz?filesrc%2FSelfTreeSelect.tsx 需求 当我们点击提交,需要返回用户名和选中树的id信息,但是,我不关要返回树的id信息,还需要返回选中树的名称 //默认返回的 {userName:梦洁,treeInfo:leaf1-value } //但是需…...

2023最新ACL大模型论文分类汇总(有代码的)

1 大模型文化道德 Knowledge of cultural moral norms in large language models url&#xff1a;https://aclanthology.org/2023.acl-long.26/code&#xff1a;https://github.com/AidaRamezani/cultural_inference 2 长文本推理 Open-ended Long Text Generation via Mask…...

Java版 招投标系统简介 招投标系统源码 java招投标系统 招投标系统功能设计

功能描述 1、门户管理&#xff1a;所有用户可在门户页面查看所有的公告信息及相关的通知信息。主要板块包含&#xff1a;招标公告、非招标公告、系统通知、政策法规。 2、立项管理&#xff1a;企业用户可对需要采购的项目进行立项申请&#xff0c;并提交审批&#xff0c;查看所…...

Ubuntu 22.04源码安装cmake 3.27.7

安装参考博客是《ubuntu安装cmake》和《Ubuntu 安装CMake》。 https://cmake.org/download是cmake官网下载的网址。 sudo wget -c https://github.com/Kitware/CMake/releases/download/v3.27.7/cmake-3.27.7.tar.gz可以下载源码&#xff0c;最后显示‘cmake-3.27.7.tar.gz’…...

无人地磅称重系统|自助过磅 料仓联动 自助卸料

上海思伟无人地磅系统 自助过磅、 自助卸料 、料仓联动 智能、省人、安全 无人监管过磅 对地磅及其相关的所有硬件进行配置和管理&#xff1b; 支持红外、道闸、车牌识别、AI分析、拍照存档、LED语音播报一体机等设备&#xff1b; 实现稳定可靠的无人监管称重功能&#xf…...

冥想第九百七十三天

1.今天周六&#xff0c;很冷的天&#xff0c;上午上了一上午的日语课。 2.下午去看了朋友刚出生的孩子。 3.充实的一天。感谢父母&#xff0c;感谢朋友&#xff0c;感谢家人&#xff0c;感谢不断进步的自己....

ROS 学习应用篇(三)话题Topic学习之自定义话题消息的类型的定义与调用

自定义消息类型的定义 Person.msg文件的定义&#xff08;数据接口文件的定义&#xff09; 创建msg文件 首先在功能包下新建msg文件夹&#xff0c;接着在该文件夹下创建文件。 定义msg文件内容 一个消息最重要的就是数据结构类型。这就需要引入一个msg文件&#xff0c;用于…...

财税服务展示预约小程序的作用是什么

财税财政往往困扰着很多公司&#xff0c;尤其是公司里没有相应职员或工作压力大的情况下&#xff0c;不少商家就会寻找代理记账、审计服务、会计代理等服务的机构。 对财政服务代理机构&#xff08;会计公司&#xff09;来说&#xff0c;市场企业多而广&#xff0c;理论上来说…...

RT-Thread提供的网络世界入口 -net组件

作为一款在RTOS领域对网络支持很丰富的RT-Thread&#xff0c;对设备联网功能的支持的工具就是net组件。 位于/rt-thread/components/net路劲下&#xff0c;作为一款基础组件&#xff0c;env与Studio的工程配置项界面的配置项都依赖该目录下的Kconfig。 我们对网络功能的选择&am…...

挑战杯推荐项目

“人工智能”创意赛 - 智能艺术创作助手&#xff1a;借助大模型技术&#xff0c;开发能根据用户输入的主题、风格等要求&#xff0c;生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用&#xff0c;帮助艺术家和创意爱好者激发创意、提高创作效率。 ​ - 个性化梦境…...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”&#xff0c;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

【kafka】Golang实现分布式Masscan任务调度系统

要求&#xff1a; 输出两个程序&#xff0c;一个命令行程序&#xff08;命令行参数用flag&#xff09;和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽&#xff0c;然后将消息推送到kafka里面。 服务端程序&#xff1a; 从kafka消费者接收…...

AtCoder 第409​场初级竞赛 A~E题解

A Conflict 【题目链接】 原题链接&#xff1a;A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串&#xff0c;只有在同时为 o 时输出 Yes 并结束程序&#xff0c;否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互

引擎版本&#xff1a; 3.8.1 语言&#xff1a; JavaScript/TypeScript、C、Java 环境&#xff1a;Window 参考&#xff1a;Java原生反射机制 您好&#xff0c;我是鹤九日&#xff01; 回顾 在上篇文章中&#xff1a;CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

【分享】推荐一些办公小工具

1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由&#xff1a;大部分的转换软件需要收费&#xff0c;要么功能不齐全&#xff0c;而开会员又用不了几次浪费钱&#xff0c;借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...

20个超级好用的 CSS 动画库

分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码&#xff0c;而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库&#xff0c;可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画&#xff0c;可以包含在你的网页或应用项目中。 3.An…...

省略号和可变参数模板

本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...