vue3 table表格封装

index.vue

<template>
  <div class="cst-list">
    <el-table :data="props.tableData" style="width: 100%" stripe ref="tableRef" :row-key="rowKey" :height="props.height"
      :size="props.tableSize" :border="props.border" @selection-change="handleSelectionChange" @select="handleSelect"
      @select-all="handleSelect" :highlight-current-row="props.highlightCurrentRow" @current-change="choiseTableItem">
      <template v-for="(item, index) in props.tHead" :key="index">
        <el-table-column v-if="item.slot" :prop="item.prop" :label="item.label" :width="item.width"
          :min-width="item.minWidth" :fixed="item.fixed" :type="item.type" :show-overflow-tooltip="item.tooltip"
          :align="item.align" :sortable="item.sortable" :formatter="item.formatter"
          :reserve-selection="item.reserveSelection">
          <template #default="scope">
            <slot :name="item.prop" :row="scope.row" :column="scope.column" :index="scope.$index"></slot>
          </template>
        </el-table-column>
        <el-table-column v-else :prop="item.prop" :label="item.label" :width="item.width" :min-width="item.minWidth"
          :fixed="item.fixed" :type="item.type" :show-overflow-tooltip="item.tooltip" :align="item.align"
          :sortable="item.sortable" :formatter="item.formatter" :reserve-selection="item.reserveSelection"
          :selectable="selectable"></el-table-column>
      </template>
    </el-table>
    <div class="page-box" :style="align">
      <el-pagination v-if="showPage" @size-change="handleSizeChange" @current-change="handleCurrentChange"
        :current-page="props.currentPage" :page-sizes="props.pageSizes" :page-size="props.pageSize" :layout="props.layout"
        :total="props.total"></el-pagination>
    </div>
  </div>
</template>
<script setup lang="ts">
import { computed, ref, inject } from 'vue'
import { Props, TypeOfYourItem } from "./type";

const emit = defineEmits([
  'select',
  'selection-change',
  'size-change',
  'update:pageSize',
  'update:currentPage',
  'current-change',
  'choiseTableItem'
])

const props: Props = defineProps({
  // 斑马纹
  stripe: {
    type: Boolean,
    default: true
  },
  // 纵向边框
  border: {
    type: Boolean,
    default: false
  },
  // 表格大小 large / default /small
  tableSize: {
    type: String,
    default: 'default'
  },
  // 表格高度
  height: {
    type: Number,
    default: null
  },
  // tooltip 主题
  tooltipEffect: {
    type: String,
    default: 'dark'
  },
  // 渲染表头数据
  tHead: {
    type: Array,
    default: () => []
  },
  tableData: {
    type: Array,
    required: true
  },
  rowKey: {
    type: Function
  },
  currentPage: {
    type: Number,
    default: 1
  },
  pageSizes: {
    type: Array,
    default: () => [10, 20, 30, 50]
  },
  pageSize: {
    type: Number,
    default: 10
  },
  layout: {
    type: String,
    default: 'total, sizes, prev, pager, next, jumper'
  },
  total: {
    type: Number,
    default: 0
  },
  // 是否展示分页
  isPage: {
    type: Boolean,
    default: true
  },
  // 分页位置 left | center | right
  pageAlign: {
    type: String,
    default: 'center'
  },
  highlightCurrentRow: {
    type: Boolean,
    default: false
  },
  // inject 抛出方法名
  provideName: {
    type: String,
    default: 'selectable'
  },
})

const align = computed(() => {
  return { 'justify-content': props.pageAlign }
})

const showPage = computed(() => {
  return props.isPage && props.tableData && props.tableData.length > 0
})

const tableRef = ref()

// 表格选中事件
const handleSelectionChange = (val: any) => {
  emit('selection-change', val)
}
// 表格选中
const handleSelect = (val: any, obj: any) => {
  emit('select', val, obj)
}
// 每页条数改变
const handleSizeChange = (val: any) => {
  emit('size-change', val)
  emit('update:pageSize', val)
}

// 当前页改变
const handleCurrentChange = (val: any) => {
  emit('update:currentPage', val)
  emit('current-change', val)
}

const handtop = () => {
  tableRef.value.toggleAllSelection() // 触发 table 表格上的全选事件
}

const selectable = inject(`${props.provideName}`, () => () => true);

defineExpose({
  tableRef,
  handtop,
  selectable
})
const choiseTableItem = (val: any) => {
  emit('choiseTableItem', val)
}

</script>

<style lang="less" scoped>
.cst-list {
  .page-box {
    display: flex;
    margin-top: 24px;
  }
}
</style>

type.ts

export type Props = {
  stripe?: boolean;
  border?: boolean;
  tableSize?: string;
  height?: number;
  tooltipEffect?: string;
  tHead?: any;
  total: number;
  isPage: boolean,
  pageAlign: string,
  tableData: any,
  highlightCurrentRow: boolean,
  currentPage: number,
  pageSizes: any,
  pageSize: number,
  layout: string,
  provideName?: string,
}

export type TypeOfYourItem = {
  slot: Boolean,
  prop: String,
  label: String,
  width: Number | String,
  minWidth: Number | String,
  fixed: String | Boolean,
  type: String,
  tooltip: Boolean,
  align: String,
  sortable: Boolean | String,
  formatter: any,
  reserveSelection: Boolean,
}

组件中使用

<template>
  <el-card>
    <el-input placeholder="请输入" style="width: 200px;"></el-input>&nbsp;
    <el-input placeholder="请输入" style="width: 200px;"></el-input>&nbsp;
    <el-input placeholder="请输入" style="width: 200px;"></el-input>&nbsp;
    <el-input placeholder="请输入" style="width: 200px;"></el-input>&nbsp;
    <el-button type="primary">搜索</el-button>
    <el-button type="primary">重置</el-button>
  </el-card>
  <br />
  <el-card>
    <systemList
      :tHead="tHead"
      :tableData="tableData"
      v-model:current-page="dataState.pageinfo.currPage"
      v-model:page-size="dataState.pageinfo.pageSize"
      v-model:isPage="isPage"
      :total="dataState.pageinfo.total"
      @size-change="sizeChange"
      @current-change="currentChange"
    >
    <template #merchantStatus="{row}">
        {{ row }}
    </template>
    <template #operate="{row}">
        <el-button type="text">查看详情</el-button>
    </template>
    </systemList>
  </el-card>
</template>
<script setup lang="ts">
import systemList from '@/components/tablePagination/index.vue'
import { reactive, ref, toRefs } from 'vue'
import { TabForm, TypeOfYourItem } from "./type";

// 不展示分页
const isPage = ref(true)

const dataState = reactive<TabForm>({
    pageinfo: {
        total: 0,
        currPage: 1,
        pageSize: 10
    },
    applyForm: {
        merchantStatus: '',
        rejectReason: ''
    },
    tableData: [
      {
        auditId: '123',
        merchantId: '123',
        merchantName: '123',
        applyTime: '123',
        merchantStatus: '123',
        auditTime: '123',
        operate: '123',
      },
      {
        auditId: '123',
        merchantId: '123',
        merchantName: '123',
        applyTime: '123',
        merchantStatus: '123',
        auditTime: '123',
        operate: '123',
      },
      {
        auditId: '123',
        merchantId: '123',
        merchantName: '123',
        applyTime: '123',
        merchantStatus: '123',
        auditTime: '123',
        operate: '123',
      },
      {
        auditId: '123',
        merchantId: '123',
        merchantName: '123',
        applyTime: '123',
        merchantStatus: '123',
        auditTime: '123',
        operate: '123',
      },
      {
        auditId: '123',
        merchantId: '123',
        merchantName: '123',
        applyTime: '123',
        merchantStatus: '123',
        auditTime: '123',
        operate: '123',
      },
    ],
})

const { tableData } = toRefs(dataState)
const tHead: TypeOfYourItem[] = [
    { align: 'center', tooltip: true, prop: 'auditId', label: '申请单号', minWidth: 100, slot: false },
    { align: 'center', tooltip: true, prop: 'merchantId', label: '商户编号', minWidth: 100, slot: false },
    { align: 'center', tooltip: true, prop: 'merchantName', label: '商户名称', minWidth: 140, slot: false },
    { align: 'center', tooltip: true, prop: 'applyTime', label: '申请时间', minWidth: 200, slot: false },
    { align: 'center', tooltip: true, prop: 'merchantStatus', label: '申请单状态', minWidth: 140, slot: true },
    { align: 'center', tooltip: true, prop: 'auditTime', label: '审核时间', minWidth: 140, slot: false },
    { align: 'center', tooltip: true, prop: 'operate', label: '操作', minWidth: 140, slot: true }
]

// 当前页数改变
const currentChange = (val: number) => {
    dataState.pageinfo.currPage = val
    // 调用列表方法
}
const sizeChange = (val: number) => {
    dataState.pageinfo.currPage = 1
    dataState.pageinfo.pageSize = val
}
</script>
<style lang="less" scoped>
</style>

type.ts

export type TabForm = {
  pageinfo: {
    total: number;
    currPage: number;
    pageSize: number;
  };
  applyForm: {
    merchantStatus: string;
    rejectReason: string;
  };
  tableData: {
    auditId: string;
    merchantId: string,
    merchantName: string,
    applyTime: string,
    merchantStatus: string,
    auditTime: string,
    operate: string,
  }[];
}

export type TypeOfYourItem = {
  slot: boolean,
  prop: string,
  label: string,
  align: number | string,
  minWidth: number | string,
  tooltip: boolean
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果你想使用第三方的 Vue 3 表格组件来封装一个表格,可以按照以下步骤进行操作: 1. 安装所需的表格组件。以 Element Plus 为例,你可以使用以下命令进行安装: ``` npm install element-plus ``` 2. 在你的 Vue 3 项目中导入并注册表格组件。在你的 main.js 文件中添加以下代码: ```javascript import { createApp } from 'vue'; import ElementPlus from 'element-plus'; import 'element-plus/dist/index.css'; import App from './App.vue'; const app = createApp(App); app.use(ElementPlus); app.mount('#app'); ``` 3. 创建一个新的 Vue 组件,用于封装表格。在这个组件中,你可以使用 Element Plus 提供的 Table 组件。 ```vue <template> <el-table :data="tableData"> <el-table-column v-for="column in tableColumns" :key="column.prop" :prop="column.prop" :label="column.label"> </el-table-column> </el-table> </template> <script> export default { data() { return { tableColumns: [ { prop: 'name', label: 'Name' }, { prop: 'age', label: 'Age' }, { prop: 'city', label: 'City' } ], tableData: [ { id: 1, name: 'John Doe', age: 25, city: 'New York' }, { id: 2, name: 'Jane Smith', age: 30, city: 'San Francisco' }, { id: 3, name: 'Bob Johnson', age: 35, city: 'Los Angeles' } ] }; } }; </script> ``` 在这个示例中,我们使用了 Element Plus 的 Table 组件,并通过 `tableColumns` 和 `tableData` 来动态渲染表格的列和数据。 你可以根据具体的表格组件的文档和需求,进一步自定义和扩展你的表格组件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值