当前位置:   article > 正文

vue3 table表格封装_vue3 table封装

vue3 table封装

index.vue

  1. <template>
  2. <div class="cst-list">
  3. <el-table :data="props.tableData" style="width: 100%" stripe ref="tableRef" :row-key="rowKey" :height="props.height"
  4. :size="props.tableSize" :border="props.border" @selection-change="handleSelectionChange" @select="handleSelect"
  5. @select-all="handleSelect" :highlight-current-row="props.highlightCurrentRow" @current-change="choiseTableItem">
  6. <template v-for="(item, index) in props.tHead" :key="index">
  7. <el-table-column v-if="item.slot" :prop="item.prop" :label="item.label" :width="item.width"
  8. :min-width="item.minWidth" :fixed="item.fixed" :type="item.type" :show-overflow-tooltip="item.tooltip"
  9. :align="item.align" :sortable="item.sortable" :formatter="item.formatter"
  10. :reserve-selection="item.reserveSelection">
  11. <template #default="scope">
  12. <slot :name="item.prop" :row="scope.row" :column="scope.column" :index="scope.$index"></slot>
  13. </template>
  14. </el-table-column>
  15. <el-table-column v-else :prop="item.prop" :label="item.label" :width="item.width" :min-width="item.minWidth"
  16. :fixed="item.fixed" :type="item.type" :show-overflow-tooltip="item.tooltip" :align="item.align"
  17. :sortable="item.sortable" :formatter="item.formatter" :reserve-selection="item.reserveSelection"
  18. :selectable="selectable"></el-table-column>
  19. </template>
  20. </el-table>
  21. <div class="page-box" :style="align">
  22. <el-pagination v-if="showPage" @size-change="handleSizeChange" @current-change="handleCurrentChange"
  23. :current-page="props.currentPage" :page-sizes="props.pageSizes" :page-size="props.pageSize" :layout="props.layout"
  24. :total="props.total"></el-pagination>
  25. </div>
  26. </div>
  27. </template>
  28. <script setup lang="ts">
  29. import { computed, ref, inject } from 'vue'
  30. import { Props, TypeOfYourItem } from "./type";
  31. const emit = defineEmits([
  32. 'select',
  33. 'selection-change',
  34. 'size-change',
  35. 'update:pageSize',
  36. 'update:currentPage',
  37. 'current-change',
  38. 'choiseTableItem'
  39. ])
  40. const props: Props = defineProps({
  41. // 斑马纹
  42. stripe: {
  43. type: Boolean,
  44. default: true
  45. },
  46. // 纵向边框
  47. border: {
  48. type: Boolean,
  49. default: false
  50. },
  51. // 表格大小 large / default /small
  52. tableSize: {
  53. type: String,
  54. default: 'default'
  55. },
  56. // 表格高度
  57. height: {
  58. type: Number,
  59. default: null
  60. },
  61. // tooltip 主题
  62. tooltipEffect: {
  63. type: String,
  64. default: 'dark'
  65. },
  66. // 渲染表头数据
  67. tHead: {
  68. type: Array,
  69. default: () => []
  70. },
  71. tableData: {
  72. type: Array,
  73. required: true
  74. },
  75. rowKey: {
  76. type: Function
  77. },
  78. currentPage: {
  79. type: Number,
  80. default: 1
  81. },
  82. pageSizes: {
  83. type: Array,
  84. default: () => [10, 20, 30, 50]
  85. },
  86. pageSize: {
  87. type: Number,
  88. default: 10
  89. },
  90. layout: {
  91. type: String,
  92. default: 'total, sizes, prev, pager, next, jumper'
  93. },
  94. total: {
  95. type: Number,
  96. default: 0
  97. },
  98. // 是否展示分页
  99. isPage: {
  100. type: Boolean,
  101. default: true
  102. },
  103. // 分页位置 left | center | right
  104. pageAlign: {
  105. type: String,
  106. default: 'center'
  107. },
  108. highlightCurrentRow: {
  109. type: Boolean,
  110. default: false
  111. },
  112. // inject 抛出方法名
  113. provideName: {
  114. type: String,
  115. default: 'selectable'
  116. },
  117. })
  118. const align = computed(() => {
  119. return { 'justify-content': props.pageAlign }
  120. })
  121. const showPage = computed(() => {
  122. return props.isPage && props.tableData && props.tableData.length > 0
  123. })
  124. const tableRef = ref()
  125. // 表格选中事件
  126. const handleSelectionChange = (val: any) => {
  127. emit('selection-change', val)
  128. }
  129. // 表格选中
  130. const handleSelect = (val: any, obj: any) => {
  131. emit('select', val, obj)
  132. }
  133. // 每页条数改变
  134. const handleSizeChange = (val: any) => {
  135. emit('size-change', val)
  136. emit('update:pageSize', val)
  137. }
  138. // 当前页改变
  139. const handleCurrentChange = (val: any) => {
  140. emit('update:currentPage', val)
  141. emit('current-change', val)
  142. }
  143. const handtop = () => {
  144. tableRef.value.toggleAllSelection() // 触发 table 表格上的全选事件
  145. }
  146. const selectable = inject(`${props.provideName}`, () => () => true);
  147. defineExpose({
  148. tableRef,
  149. handtop,
  150. selectable
  151. })
  152. const choiseTableItem = (val: any) => {
  153. emit('choiseTableItem', val)
  154. }
  155. </script>
  156. <style lang="less" scoped>
  157. .cst-list {
  158. .page-box {
  159. display: flex;
  160. margin-top: 24px;
  161. }
  162. }
  163. </style>

type.ts

  1. export type Props = {
  2. stripe?: boolean;
  3. border?: boolean;
  4. tableSize?: string;
  5. height?: number;
  6. tooltipEffect?: string;
  7. tHead?: any;
  8. total: number;
  9. isPage: boolean,
  10. pageAlign: string,
  11. tableData: any,
  12. highlightCurrentRow: boolean,
  13. currentPage: number,
  14. pageSizes: any,
  15. pageSize: number,
  16. layout: string,
  17. provideName?: string,
  18. }
  19. export type TypeOfYourItem = {
  20. slot: Boolean,
  21. prop: String,
  22. label: String,
  23. width: Number | String,
  24. minWidth: Number | String,
  25. fixed: String | Boolean,
  26. type: String,
  27. tooltip: Boolean,
  28. align: String,
  29. sortable: Boolean | String,
  30. formatter: any,
  31. reserveSelection: Boolean,
  32. }

组件中使用

  1. <template>
  2. <el-card>
  3. <el-input placeholder="请输入" style="width: 200px;"></el-input>&nbsp;
  4. <el-input placeholder="请输入" style="width: 200px;"></el-input>&nbsp;
  5. <el-input placeholder="请输入" style="width: 200px;"></el-input>&nbsp;
  6. <el-input placeholder="请输入" style="width: 200px;"></el-input>&nbsp;
  7. <el-button type="primary">搜索</el-button>
  8. <el-button type="primary">重置</el-button>
  9. </el-card>
  10. <br />
  11. <el-card>
  12. <systemList
  13. :tHead="tHead"
  14. :tableData="tableData"
  15. v-model:current-page="dataState.pageinfo.currPage"
  16. v-model:page-size="dataState.pageinfo.pageSize"
  17. v-model:isPage="isPage"
  18. :total="dataState.pageinfo.total"
  19. @size-change="sizeChange"
  20. @current-change="currentChange"
  21. >
  22. <template #merchantStatus="{row}">
  23. {{ row }}
  24. </template>
  25. <template #operate="{row}">
  26. <el-button type="text">查看详情</el-button>
  27. </template>
  28. </systemList>
  29. </el-card>
  30. </template>
  31. <script setup lang="ts">
  32. import systemList from '@/components/tablePagination/index.vue'
  33. import { reactive, ref, toRefs } from 'vue'
  34. import { TabForm, TypeOfYourItem } from "./type";
  35. // 不展示分页
  36. const isPage = ref(true)
  37. const dataState = reactive<TabForm>({
  38. pageinfo: {
  39. total: 0,
  40. currPage: 1,
  41. pageSize: 10
  42. },
  43. applyForm: {
  44. merchantStatus: '',
  45. rejectReason: ''
  46. },
  47. tableData: [
  48. {
  49. auditId: '123',
  50. merchantId: '123',
  51. merchantName: '123',
  52. applyTime: '123',
  53. merchantStatus: '123',
  54. auditTime: '123',
  55. operate: '123',
  56. },
  57. {
  58. auditId: '123',
  59. merchantId: '123',
  60. merchantName: '123',
  61. applyTime: '123',
  62. merchantStatus: '123',
  63. auditTime: '123',
  64. operate: '123',
  65. },
  66. {
  67. auditId: '123',
  68. merchantId: '123',
  69. merchantName: '123',
  70. applyTime: '123',
  71. merchantStatus: '123',
  72. auditTime: '123',
  73. operate: '123',
  74. },
  75. {
  76. auditId: '123',
  77. merchantId: '123',
  78. merchantName: '123',
  79. applyTime: '123',
  80. merchantStatus: '123',
  81. auditTime: '123',
  82. operate: '123',
  83. },
  84. {
  85. auditId: '123',
  86. merchantId: '123',
  87. merchantName: '123',
  88. applyTime: '123',
  89. merchantStatus: '123',
  90. auditTime: '123',
  91. operate: '123',
  92. },
  93. ],
  94. })
  95. const { tableData } = toRefs(dataState)
  96. const tHead: TypeOfYourItem[] = [
  97. { align: 'center', tooltip: true, prop: 'auditId', label: '申请单号', minWidth: 100, slot: false },
  98. { align: 'center', tooltip: true, prop: 'merchantId', label: '商户编号', minWidth: 100, slot: false },
  99. { align: 'center', tooltip: true, prop: 'merchantName', label: '商户名称', minWidth: 140, slot: false },
  100. { align: 'center', tooltip: true, prop: 'applyTime', label: '申请时间', minWidth: 200, slot: false },
  101. { align: 'center', tooltip: true, prop: 'merchantStatus', label: '申请单状态', minWidth: 140, slot: true },
  102. { align: 'center', tooltip: true, prop: 'auditTime', label: '审核时间', minWidth: 140, slot: false },
  103. { align: 'center', tooltip: true, prop: 'operate', label: '操作', minWidth: 140, slot: true }
  104. ]
  105. // 当前页数改变
  106. const currentChange = (val: number) => {
  107. dataState.pageinfo.currPage = val
  108. // 调用列表方法
  109. }
  110. const sizeChange = (val: number) => {
  111. dataState.pageinfo.currPage = 1
  112. dataState.pageinfo.pageSize = val
  113. }
  114. </script>
  115. <style lang="less" scoped>
  116. </style>

type.ts

  1. export type TabForm = {
  2. pageinfo: {
  3. total: number;
  4. currPage: number;
  5. pageSize: number;
  6. };
  7. applyForm: {
  8. merchantStatus: string;
  9. rejectReason: string;
  10. };
  11. tableData: {
  12. auditId: string;
  13. merchantId: string,
  14. merchantName: string,
  15. applyTime: string,
  16. merchantStatus: string,
  17. auditTime: string,
  18. operate: string,
  19. }[];
  20. }
  21. export type TypeOfYourItem = {
  22. slot: boolean,
  23. prop: string,
  24. label: string,
  25. align: number | string,
  26. minWidth: number | string,
  27. tooltip: boolean
  28. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/684228
推荐阅读
相关标签
  

闽ICP备14008679号