赞
踩
大家好,我是一个8年前端开发经验的新博主(实战react方向较多),最近两年互联网行业动荡,工作不稳定,想积累点自己的项目实践经验以备不时之需。第一弹!分享一下最近使用vue3.0二次封装过的el-table组件,带有分页功能,以及操作列按动态数据有条件渲染!希望可以帮助各位在职前端小伙伴解决一些实际问题。
下一弹分享自定义搜索表单组件<SearchForm/>,喜欢的记得点个赞哦~
知识点:
1、二次封装el-table,减少重复写很多标签
2、table表格自带翻页页签pagination
3、序号列按当前页累加计算
4、操作列按数据有条件渲染
直接先看效果图:(前提先安装UI组件库:npm element-plus --save)
代码比较多,原因是我写的比较全,有经验的可以直接看关键的地方!!
首先,看二次封装过的Table组件代码
- <!--
- * @Author: Cocoon_xu
- * @LastEditTime: 2024-02-18 16:41:12
- * @Description: 二次封装表格组件,带翻页控件
- -->
- <template>
- <!-- 表格 -->
- <el-table
- :data="tableData"
- :border="border"
- :stripe="stripe"
- v-loading="loading"
- style="width: 100%; overflow-x: auto;"
- @selection-change="selectionChange"
- >
- <!-- 复选框 -->
- <el-table-column v-if="isSelectabled" type="selection" width="50" />
-
- <template v-for="(column,index) in tableColunms" :key="index">
- <!-- 文字不需要特殊显示 -->
- <el-table-column
- :type="column.type"
- :prop="column.prop"
- :label="column.label"
- :fixed="column.fixed || true"
- :sortable="column.sortable || false"
- :show-overflow-tooltip="column.overHidden || false"
- :width="column.width"
- :min-width="column.minWidth || '50px'"
- :align="column.align || 'center'"
- :formatter="column.formatter"
- >
- <!-- <template #default="scope" >
- <span v-if="scope.column.type !=='index'">{{ scope.row[column.prop] ? scope.row[column.prop] : "" }}</span>
- <span v-if="scope.column.type ==='index'">{{ (pagination.pageNum-1) * pagination.pageSize + scope.$index + 1}}</span>
- </template> -->
- </el-table-column>
- </template>
-
- <!-- 操作列插槽 -->
- <el-table-column
- label="操作"
- fixed="right"
- align="center"
- >
- <template #default="scope">
- <!-- 当操作按钮少于3个,建议使用mode:'inline',默认为'dropdown'模式 -->
- <table-dropdown
- :actionColumns='()=>actionColumns(scope)'
- :scope="scope"
- :mode="actionMode || 'dropdown'"
- />
- </template>
- </el-table-column>
- </el-table>
-
- <!-- 分页 -->
- <div class="pagination">
- <el-pagination
- v-model:page-size="pagination.pageSize"
- v-model:current-page="pagination.pageNum"
- :total="total"
- :layout="layout"
- :page-sizes="pageSizesArr"
- @size-change="sizeChange"
- @current-change="currentChange"
- />
- </div>
- </template>
-
- <script setup>
- import { defineProps, defineEmits } from 'vue';
- import TableDropdown from '@/components/TableDropdown/dropdown.vue'
-
- const emits = defineEmits(['sizeChange', 'currentChange'])
- const props = defineProps({
- tableData:{
- type: Array,
- default:[]
- },
- tableColunms:{
- type: Array,
- default: []
- },
- actionColumns:{
- type: Function,
- default:() => {}
- },
- actionMode:{
- type: String,
- default: 'dropdown'
- },
- opColunms:{
- type: Object,
- default: {}
- },
- border:{ // 是否带有纵向边框
- type: Boolean,
- default: false
- },
- loading:{
- type: Boolean,
- default: false
- },
- isSelectabled: { // 是否带有复选框
- type: Boolean,
- default: false
- },
- pagination: {
- type: Object,
- default: () => {
- return {pageSize: 10, pageNum: 1}
- }
- },
- pageSizesArr:{
- type: Array,
- default: () => {
- return [10,20,30,50]
- }
- },
- stripe: { // 是否为斑马纹 table
- type: Boolean,
- default: false
- },
- total: {
- type: Number,
- required: true,
- default: 0
- },
- layout:{
- type: String,
- default: "total, sizes, prev, pager, next, jumper"
- }
- })
- // 触发选择框
- const selectionChange = (val) => {
- console.log(val)
- }
- // 切换分页size
- const sizeChange = (val) => {
- emits('sizeChange', val)
- }
- // 切换分页
- const currentChange = (val) => {
- emits('currentChange', val)
- }
-
- </script>
-
- <style lang="scss">
- /* .el-table .warning-row {
- --el-table-tr-bg-color: var(--el-color-warning-light-9);
- }
- .el-table .success-row {
- --el-table-tr-bg-color: var(--el-color-success-light-9);
- } */
- .pagination{
- margin: 15px auto;
- display: flex;
- justify-content: center;
- }
- .el-table{
- .el-table__header .cell{
- color: #000;
- }
- }
- </style>
我们可以看到Table组件里调用了TableDropdown,也是我自定义的一个组件,用于表格的操作列按表格数据有条件渲染成不同的按钮。下面为此组件的代码:
- <!--
- * @Author: Cocoon_xu
- * @LastEditTime: 2024-02-18 16:38:25
- * @Description: 表格操作列表
- -->
- <script setup>
- import { defineProps } from 'vue';
- const props = defineProps({
- actionColumns:{
- type: Function,
- default: () => {}
- },
- scope: {
- type: Object,
- default: {}
- },
- mode: {
- type: String,
- default: 'dropdown'
- }
- })
-
- </script>
-
- <template>
- <template v-if="mode === 'inline'">
- <el-button
- v-for="(item,index) in actionColumns(scope)"
- text
- :key="index"
- :icon="item.icon"
- :disabled="item.disabled"
- :style="{marginLeft:0, color: item.color}"
- @click="(e)=>{
- e.preventDefault();
- let row = JSON.parse(JSON.stringify(scope.row))
- item.event(row);
- }"
- >
- {{ item.label }}
- </el-button>
- </template>
- <template v-else>
- <el-dropdown>
- <span class="el-dropdown-link">
- <el-icon color="#409EFC"><Menu/></el-icon>
- </span>
- <template #dropdown>
- <el-dropdown-menu>
- <el-dropdown-item
- v-for="(item, index) in actionColumns(scope)"
- :key="index"
- :icon="item.icon"
- :disabled="item.disabled"
- @click="(e)=>{
- e.preventDefault();
- let row = JSON.parse(JSON.stringify(scope.row))
- item.event(row);
- }"
- >
- <span>{{ item.label }}</span>
- </el-dropdown-item>
- </el-dropdown-menu>
- </template>
- </el-dropdown>
- </template>
- </template>
-
- <style lang="scss">
- .table-menu{
- background: transparent;
- .el-menu-item{
- padding: 0;
- height: 24px;
- line-height: 24px;
- }
- }
- </style>
最后,就是调用组件的使用
- <!--
- * @Author: Cocoon_xu
- * @LastEditTime: 2024-02-18 16:38:25
- * @Description: 组件调用
- -->
-
- <template>
- <div class="table-box">
- <common-table
- :loading="loading"
- :tableColunms="tableColunms"
- :actionColumns="actionColumns"
- :tableData="tableData"
- :pagination="pagination"
- :total="total"
- :stripe="true"
- :isSelectabled="false"
- @currentChange="handleCurrentChange"
- @sizeChange="handleSizeChange"
- ></common-table>
- </div>
- </template>
-
- <script setup>
- import { ref, onMounted, h } from 'vue';
- import CommonTable from '@/components/Table/index.vue';
-
- const loading = ref(false)
- const tableData = ref([])
- const total = ref(0)
- const pagination = ref({
- pageSize: 10,
- pageNum: 1
- })
- const tableColunms = [
- {
- label:'序号',
- width: 80,
- formatter:(row, columm, cellValue, index) => {
- return (pagination.value.pageNum-1) * pagination.value.pageSize + index + 1
- }
- },{
- label:'标题',
- prop:'title',
- minWidth: 120,
- overHidden: true
- },{
- label:'发布人',
- prop:'sendByName',
- },{
- label:'审核状态',
- prop:'submitStatus',
- minWidth: 70,
- formatter: (row, column, cellValue, index) => {
- if(cellValue === '1'){
- return h('span',{class:'draft'},'草稿')
- }else if(row.auditStatus === 'active'){
- return h('span',{class:'waitExamine'},'待审核')
- }else if(row.auditStatus === 'completed'){
- return h('span',{class:'pass'},'已通过')
- }else if(row.auditStatus === 'terminated'){
- return h('span',{class:'error'},'审批终止')
- }else if(row.auditStatus === 'rejected'){
- return h('span',{class:'error'},'被退回')
- }else{
- return '--'
- }
- }
- }
- ]
- // 操作列按钮
- const actionColumns = (scope) =>{
- let btns = [{
- label:'查看',
- type:'check',
- icon:'View',
- color:'#409EFC',
- disabled: false,
- event:(row) => {
- console.log(row)
- detail(row)
- }
- }];
- if(scope.row.auditStatus == 1 || (scope.row.auditStatus == 'rejected')){
- btns.push({
- label:'编辑',
- type:'edit',
- icon:'Edit',
- color:'#409EFC',
- disabled: false,
- event:(row) => {
- console.log(row)
- }
- })
- }
- if((scope.row.sendStatus == 0 && scope.row.auditStatus != 'completed'))){
- btns.push({
- label:'删除',
- type:'delete',
- icon:'Delete',
- color:'#409EFC',
- disabled: false,
- event:(row) => {
- console.log(row)
- }
- })
- }
- return btns;
- }
-
- // 切换当前分页
- const handleCurrentChange = (val) => {
- pagination.value = {
- pageNum: val,
- pageSize: pagination.value.pageSize
- }
- getConListInfoPagefn();
- }
- // 切换分页size
- const handleSizeChange = (val) => {
- pagination.value = {
- pageNum: 1,
- pageSize: val
- }
- getConListInfoPagefn();
- }
-
-
- </script>
代码部分结束!希望对你有所帮助!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。