脚本之家

电脑版
提示:原网页已由神马搜索转码, 内容由www.jb51.net提供.
您的位置:首页网络编程JavaScriptjavascript类库vue.js→ vue3 el-table 表格组件封装

vue3 实现关于 el-table 表格组件的封装及调用方法

  更新时间:2024年06月27日 15:07:50  作者:程序员-小李 
这篇文章主要介绍了vue3 实现关于 el-table 表格组件的封装及调用方法,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧

一、示例图:

二、组件

<template>
<div class="sn-table" :class="props.colorType === 1 ? '' : 'bg-scroll'">
<el-table :data="tableData" :row-class-name="tableRowClassName" height="500" style="width: 100%;"
:default-sort="[{ prop: '正确率', order: 'descending' },{ prop: '未答题数', order: 'descending' }]"
:class="props.colorType === 1 ? '' : 'bg-scroll'">
<el-table-column align="center" :prop="item.keyName"
:sortable="item.keyName==='正确率'&&props.isExistSelect||item.keyName==='未答题数'&&props.isExistSelect?true:false"
:label="item.keyName" v-for="item in columns"
:width="item.width ? item.width + 'px' : ''">
<template #default="scope">
<div v-if="item.keyName==='正确率'&&props.isExistSelect" class="tag-list">
<el-progress :percentage="scope.row[item.keyName]" color="#00B386" :stroke-width="10" :text-inside="false"/>
</div>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script lang='ts' setup>
type TProps = {
tableData: any[]
columns: any[],
colorType: number, // 颜色类型
isExistSelect: boolean // 是否存在筛选项
}
const props = withDefaults(defineProps<TProps>(), {})
const tableRowClassName = ({ rowIndex }: { rowIndex: number }) => {
if (rowIndex % 2 === 1) {
return props.colorType === 1 ? 'odd-row' : 'class-odd-row'
} else {
return props.colorType === 1 ? 'even-row' : 'class-even-row'
}
}
</script>
<style lang='scss' scoped>
.bg-scroll {
border-radius: 10px;
height: 96%;
overflow-y: scroll;
&::-webkit-scrollbar {
width: 5px;
height: 0 !important;
}
&::-webkit-scrollbar-thumb {
border-radius: 10px;
background: #eeeeee;
}
}
.sn-table {
padding: 0 10px 0 20px;
:deep(.el-table) {
color: #ffffff !important;
tr {
td {
border: none;
padding: 16px 0;
font-size: 15px;
}
}
th.el-table__cell {
background: #141414 !important;
border: none;
color: #00B386;
font-size: 14px;
font-weight: 400;
}
.even-row {
background-color: #333 !important;
}
.odd-row {
background-color: #141414 !important;
}
.class-even-row {
background-color: #333 !important;
}
.class-odd-row {
background-color: #00B386 !important;
}
}
:deep(.el-scrollbar__wrap--hidden-default) {
background: #141414 !important;
}
:deep(.el-table--enable-row-hover) {
.el-table__body {
tr:hover>td.el-table__cell {
color: #8C8C8C;
background: #333 !important;
}
}
}
:deep(.el-table__inner-wrapper) {
&::before {
background-color: transparent;
}
}
:deep(.el-table .ascending .sort-caret.ascending){
border-bottom-color:#00B386 !important;
}
:deep(.el-table .descending .sort-caret.descending){
border-top-color:#00B386 !important;
}
.ok-text{
font-size: 35px;
font-weight: 300;
}
.tag-list{
width: 100%;
padding: 2px 0;
.tag-btn{
border-radius: 5px;
border: 1px solid #EF8714;
color: #EF8714;
padding: 1px 10px;
margin-right: 15px;
&:last-child{
margin-right: 0;
}
}
}
}
:deep(.el-progress){
width: 185px;
margin: 0 auto;
}
:deep(.el-progress__text){
span{
font-size: 16px;
}
}
:deep(.el-progress-bar__outer){
background: #D9D9D9;
}
</style>

三、页面调用

<details-table :tableData="knowInfo" :columns="knowColumns" :isExistSelect="false" :colorType="1"/>
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import CanvasVideo from "@/components/CanvasVideo.vue"
const knowInfo = ref<any[]>([])
const knowColumns = ref<any[]>([])
onMounted(()=>{
init()
})
//数据处理
const init = () => {
const datas = ref([
{studentName:'陈佳颖',correctRate:0,noAnswerCount:13},
{studentName:'丁靖芸',correctRate:0,noAnswerCount:13},
{studentName:'谷雨恒',correctRate:0,noAnswerCount:13},
{studentName:'欧阳江源',correctRate:0,noAnswerCount:13},
{studentName:'任行宽',correctRate:0,noAnswerCount:13},
{studentName:'任彦宇',correctRate:0,noAnswerCount:13},
{studentName:'王骁南',correctRate:0,noAnswerCount:13},
{studentName:'吴骏扬',correctRate:0,noAnswerCount:13}
])
if (datas && datas.length > 0) {
datas.forEach((it: any, index:number) => {
knowInfo.value.push({
'行号': index+1,
'姓名': it.studentName,
'正确率': it.correctRate,
'未答题数': it.noAnswerCount
})
})
for (const key in knowInfo.value[0]) {
knowColumns.value.push({
keyName: key,
width: key === '行号' ? 140 : null
})
}
}
}
</script>

四、其他

(1)自定义标题

<el-table :data="datas" style="width: 100%;">
<el-table-column label="" prop="name" align="center">
<template #header>
姓名
</template>
</el-table-column>
</el-table>

(2)自定义下标

<el-table :data="datas" style="width: 100%;">
<el-table-column label="行号" align="center">
<template #default="{$index}">
{{$index+1}}
</template>
</el-table-column>
</el-table>

(3)自定义内容

<el-table :data="datas" style="width: 100%;">
<el-table-column label="姓名" prop="name" align="center">
<template #default="scope">
<div>{{scope.row.name}}s</div>
</template>
</el-table-column>
</el-table>

(4)添加排序(升序、降序)

<el-table :data="datas" style="width: 100%;"
:default-sort="[{ prop: 'rank', order: 'descending' },{ prop: 'time', order: 'descending' }]">
<el-table-column label="排名" prop="rank" sortable align="center"/>
<el-table-column label="时长" prop="time" sortable align="center"/>
</el-table>

(5)多选与单选

1. 单选

<el-table :data="datas" style="width: 100%;"
row-key="id" ref="multipleTable" highlight-current-row @row-click="rowselect" @selection-change="selectGroupChange">
<el-table-column type="selection" width="55" />
<el-table-column label="排名" prop="rank" align="center"/>
<el-table-column label="时长" prop="time" align="center"/>
</el-table>
<script setup lang="ts">
import { ref } from "vue"
const multipleTable = ref()
const handleList = ref([])
// 设置单选||显示高亮
const rowselect = (row:any) => {
multipleTable.value.toggleRowSelection(row)
}
// 选择多个单选框,只取最后选中的那一个
const selectGroupChange = (row:any) => {
if (row.length > 1) {
multipleTable.value.clearSelection()
multipleTable.value.toggleRowSelection(row.pop())
return
}
if (row.length == 1) {
handleList.value = row
} else {
handleList.value = []
}
}
</script>
<style lang='scss' scoped>
// 隐藏表头选择框
:deep(.el-table__header){
.el-checkbox{
display: none;
}
}
</style>

2. 多选

<el-table :data="datas" style="width: 100%;"
row-key="id" @select="handleSelectionChange" @select-all="handleAllChange">
<el-table-column type="selection" width="55" />
<el-table-column label="排名" prop="rank" align="center"/>
<el-table-column label="时长" prop="time" align="center"/>
</el-table>
<script setup lang="ts">
// 选择多个选择框
const handleSelectionChange = (selecteds: any, row: any) => {}
// 全选
const handleAllChange= (row:any) => {}
</script>

五、实例(实现树形数据与懒加载)

示例图:通过点击当前节点,调用接口展示下一节点,实现列表的增删改查

1、添加修改组件 EditForm.vue

<template>
<div>
<el-form
ref="menuEditForm"
:model="form"
:label-width="formLabelWidth"
:size="size"
:rules="rules"
clearable
>
<el-row>
<el-col :span="12">
<el-form-item label="父级字典:" prop="parentId">
<el-cascader ref="myCascader" v-model="form.parentId" :props="{ checkStrictly: true,emitPath:false,expandTrigger:'hover' }" :options="menuTree" :show-all-levels="false" placeholder="请选择父级字典" clearable />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="字典名称:" :rules="rules.Required" prop="dictionaryName">
<el-input
v-model="form.dictionaryName"
autocomplete="off"
:show-word-limit="true"
placeholder="请输入字典名称"
/>
</el-form-item>
</el-col>
</el-row>
<el-row v-if="title==='添加字典'">
<el-col :span="24">
<el-form-item label="字典编码:" :rules="rules.Required" prop="dictionaryCode">
<el-input
v-model="form.dictionaryCode"
autocomplete="off"
:show-word-limit="true"
placeholder="请输入字典编码"
/>
</el-form-item>
</el-col>
</el-row>
<el-form-item
label="备注:"
prop="remark"
>
<el-input
v-model="form.remark"
type="textarea"
maxlength="200"
:show-word-limit="true"
autocomplete="off"
/>
</el-form-item>
</el-form>
</div>
</template>
<script>
import { getChildrens, getDictionaryInfo, EditDictionary } from '@/api/dictionary'
import rules from '@/utils/rules'
export default {
props: {
id: {
type: Number,
default: 0
},
title: {
type: String,
default: ''
}
},
data() {
return {
menuTree: [], // 字典树
rules: rules,
formLabelWidth: '120px',
size: 'small',
loading: false,
form: {
id: this.id,
parentId: 0,
parentDictionaryName: '',
dictionaryCode: '',
dictionaryName: '',
remark: '',
deleteState: true
}
}
},
created() {
this.fetchInitData()
},
methods: {
handlePagedCallback() {
this.$emit('handlePagedCallback')
},
handleSubmitForm() {
this.$refs['menuEditForm'].validate((valid) => {
if (valid) {
this.loading = true
EditDictionary(this.form).then((res) => {
this.loading = false
if (res.code === 200) {
if (res.data) {
this.$message.success('操作成功')
this.handlePagedCallback()
} else {
this.$message.error('操作失败')
}
} else {
this.$message.error(res.message)
}
})
}
})
},
handleResetForm() {
if (this.$refs['menuEditForm']) {
this.$refs['menuEditForm'].resetFields()
}
},
fetchInitData() {
getChildrens().then((res) => {
if (res.code === 200) {
this.menuTree = JSON.parse(JSON.stringify(res.data).replace(/id/g, 'value').replace(/dictionaryName/g, 'label'))
this.fetchFormData()
}
})
},
fetchFormData() {
this.handleResetForm()
if (this.id !== 0) {
const id = { Id: this.id }
getDictionaryInfo(id).then((res) => {
if (res.code === 200) {
this.form = Object.assign(this.form, res.data)
}
})
}
}
}
}
</script>

2、主页面 index.vue

<template>
<div class="app-container">
<div class="search-container">
<!-- 搜索项目 -->
<el-form :inline="true" :model="search" size="small">
<el-form-item>
<el-input v-model="search.keyword" placeholder="字典名称" />
</el-form-item>
<el-form-item>
<el-button
v-rolebtn="'BTN-ZDGL-查询'"
type="primary"
icon="el-icon-search"
@click="handleReloadPaged"
>查询</el-button>
</el-form-item>
</el-form>
</div>
<div class="toolbar-container">
<!-- 按钮组 -->
<el-button
v-rolebtn="'BTN-ZDGL-新增字典'"
type="success"
size="small"
plain
@click="AddDialog"
>新增</el-button>
<el-button
v-rolebtn="'BTN-ZDGL-编辑字典'"
type="primary"
size="small"
plain
@click="EditDialog"
>修改</el-button>
<el-button
v-rolebtn="'BTN-ZDGL-删除字典'"
type="danger"
size="small"
plain
@click="handleDelete"
>删除</el-button>
</div>
<el-table
ref="myTable"
:data="table.data"
:border="table.border"
style="width: 100%"
empty-text="暂无数据"
row-key="id"
lazy
:load="lazyload"
:default-expand-all="false"
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="60" />
<el-table-column prop="dictionaryName" label="字典名称" />
<el-table-column prop="dictionaryCode" label="字典编码" />
<el-table-column prop="parentDictionaryName" label="父级字典名称" />
<el-table-column prop="createTime" label="创建时间" />
<el-table-column prop="remark" label="备注" />
</el-table>
<Pagination
:total="pagination.total"
:current="pagination.index"
:page-size="pagination.size"
@handlePaginationChange="handlePaginationChange"
@handleSizeChange="handlePaginationChange"
/>
<div class="dialog-container">
<el-dialog
v-if="dialog.edit.visible"
ref="menuEditDialog"
:title="dialog.edit.title"
:visible.sync="dialog.edit.visible"
:width="dialog.edit.width"
:close-on-click-modal="dialog.close"
:close-on-press-escape="dialog.close"
>
<EditForm
:id="dialog.edit.id"
ref="Submit"
:title="dialog.edit.title"
@handlePagedCallback="handleEditCallback"
/>
<span slot="footer" class="dialog-footer">
<el-button @click="dialog.edit.visible = false">取 消</el-button>
<el-button type="primary" @click="Submit">确 定</el-button>
</span>
</el-dialog>
</div>
</div>
</template>
<script>
import Pagination from '@/components/Pagination'
import EditForm from './EditForm'
import { getDictionaryNext, getDictionaryRoute, DeleteDictionaryRoute } from '@/api/dictionary'
export default {
components: { Pagination, EditForm },
data() {
return {
search: {
keyword: ''
},
searchId: 0,
// 表格数据
table: {
data: [],
selectRows: [],
border: false
},
currChildren: [],
// 分页数据
pagination: {
index: 1,
size: 20,
total: 0
},
// 弹出层
dialog: {
close: false, // 是否关闭
edit: {
id: 0,
title: '修改字典', // 弹出层title
visible: false, // 弹出层是否显示
width: '800px' // 弹出层宽度
}
},
layzNode: null,
layztreeNode: null,
layzresolve: null
}
},
created() {
this.getDictionaryList()
},
methods: {
lazyload(tree, treeNode, resolve) {
if (tree) {
var data = {
Id: tree.id
}
getDictionaryNext(data).then((res) => {
if (res.code === 200) {
this.layzNode = tree
this.layztreeNode = treeNode
this.layzresolve = resolve
resolve(res.data)
}
})
}
},
Submit() {
this.$refs.Submit.handleSubmitForm()
},
// 勾选
handleSelectionChange(selection) {
this.table.selectRows = selection
},
// 新增
AddDialog() {
this.dialog.edit.id = 0
this.dialog.edit.title = '添加字典'
this.dialog.edit.visible = true
},
// 修改
EditDialog() {
if (this.table.selectRows.length !== 1) {
this.$message.warning('请选择要修改的字典')
} else {
this.dialog.edit.id = this.table.selectRows[0].id
this.dialog.edit.title = '修改字典'
this.dialog.edit.visible = true
}
},
// 修改成功回调
handleEditCallback() {
this.dialog.edit.visible = false
this.dialog.edit.id = 0
this.$nextTick(() => {
this.$set(this.$refs.myTable.store.states.lazyTreeNodeMap, this.layzNode.id, [])
this.lazyload(this.layzNode, this.layztreeNode, this.layzresolve)
this.getDictionaryList()
})
},
// 删除
handleDelete() {
if (this.table.selectRows.length === 0) {
this.$message.warning('未勾选记录')
return
}
const ids = []
this.table.selectRows.forEach((it) => {
ids.push(it.id)
})
this.$confirm('此操作将永久删除勾选记录, 是否继续?').then(() => {
DeleteDictionaryRoute(ids).then((res) => {
if (res.code === 200) {
if (res.data) {
this.$nextTick(() => {
this.getDictionaryList()
this.$set(this.$refs.myTable.store.states.lazyTreeNodeMap, this.layzNode.id, [])
this.lazyload(this.layzNode, this.layztreeNode, this.layzresolve)
})
this.$message.success('操作成功')
} else {
this.$message.error('操作失败')
}
} else {
this.$message.error(res.message)
}
})
})
},
// 列表接口
getDictionaryList() {
var data = {
searchName: this.search.keyword,
searchId: this.searchId,
pageIndex: this.pagination.index,
pageSize: this.pagination.size
}
getDictionaryRoute(data).then((res) => {
if (res.code === 200) {
this.pagination.total = res.data.total
this.table.data = res.data.data
}
})
},
// 重载表格
handleReloadPaged() {
this.pagination.index = 1
this.getDictionaryList()
},
// 分页变更
handlePaginationChange(data) {
this.pagination.index = data.current
this.pagination.size = data.pageSize
this.getDictionaryList()
}
}
}
</script>

     希望我的愚见能够帮助你哦~,若有不足之处,还望指出,你们有更好的解决方法,欢迎大家在评论区下方留言支持,大家一起相互学习参考呀~

到此这篇关于vue3 实现关于 el-table 表格组件的封装以及调用的文章就介绍到这了,更多相关vue3 el-table 表格组件封装内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

    • 在开发业务场景中我们通常遇到一些奇怪的需求,下面这篇文章主要给大家介绍了关于el-select如何获取当前选中的对象所有(item)数据的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
      2023-11-11
    • 这篇文章主要介绍了vue.js过滤器+ajax实现事件监听及后台php数据交互,结合实例形式分析了vue.js前台过滤器与ajax后台数据交互相关操作技巧,需要的朋友可以参考下
      2018-05-05
    • 这篇文章主要为大家介绍了使用v-memo缓存模板子树提高应用性能详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
      2022-09-09
    • 很多朋友遇到这样的问题当vue打包后显示空白问题,遇到这样的问题怎么处理呢?下面脚本之家小编给大家分享下vue打包后显示空白正确处理方法,感兴趣的朋友一起看看吧
      2017-11-11
    • 这篇文章主要介绍了vue3父子通信ref,toRef,toRefs使用实例详解,分别介绍了ref是什么、toRef是什么及toRefs是什么和最佳使用方式,结合示例代码给大家讲解的非常详细,需要的朋友可以参考下
      2023-10-10
    • 这篇文章主要介绍了vue项目中axios请求网络接口封装的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
      2018-12-12
    • 这篇文章主要介绍了详解vue填坑之解决部分浏览器不支持pushState方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
      2018-07-07
    • 下面小编就为大家分享一篇vue+element-ui+ajax实现一个表格的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
      2018-03-03
    • 这篇文章主要为大家详细介绍了Vue+canvas实现视频截图功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
      2022-07-07
    • 这篇文章主要介绍了vue如何循环给对象赋值,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
      2022-04-04

    最新评论