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

Vue3+TS项目封装一个公共的el-table组件二次封装

前言

支持动态传入列,列内容可以指定插槽,指定格式化显示

样式没太写,主要分享基础功能封装

效果

Table组件代码BaseTable.vue

<template>
  <el-table :data="data" border>
    <template v-for="col in columns" :key="col.prop">
      <el-table-column :prop="col.prop" :label="col.label" :width="col.width" show-overflow-tooltip>
        <template #default="{ row }">
          <slot v-if="col.slot" :name="col.slot"></slot>
          <!-- 因为这个内容不是通过表格的prop直接绑定的,所以表格自带的溢出省略号失效,自己写下 -->
          <div v-else class="text-overflow">{{ getFormatter(col, row[col.prop]) }}</div>
        </template>
      </el-table-column>
    </template>
  </el-table>
  <br>
  <template v-if="isShowPage">
    <el-pagination v-model:currentPage="currentPage1" v-model:page-size="pageSize1" :page-sizes="[10, 20, 30, 40]"
      background layout="total, sizes, prev, pager, next, jumper" :total="totalSize" @size-change="sizeChange"
      @current-change="currentChange" />
  </template>
</template>
<script lang="ts" setup>
import { computed, ref } from 'vue';

export interface BaseTableConfig {
  data: any[];
  columns: TableColumn[];
  current?: number;
  pageSize?: number;
  totalSize?: number;
  [key: string]: any;
}
export interface TableColumn {
  prop?: string;
  label: string;
  slot?: string;
  width?: number;
  formatter?: Function;
  [key: string]: any;
}
const emit = defineEmits(['update:pageSize', 'update:currentPage', 'pageChange'])
const props = defineProps({
  data: {
    type: Array,
    default: () => ([])
  },
  columns: {
    type: Array<any>,
    default: () => ([])
  },
  currentPage: {
    type: Number,
    default: 1,
  },
  pageSize: {
    type: Number,
    default: 10,
  },
  totalSize: {
    type: Number,
    default: 0,
  },
  isShowPage: {
    type: Boolean,
    default: true,
  }
});
const currentPage1 = ref(props.currentPage);
const pageSize1 = ref(props.pageSize);
const getFormatter = (col: any, value: any) => {
  if (col.formatter) {
    return col.formatter(value);
  }
  return value;
}
const sizeChange = (val: number) => {
  emit('update:pageSize', val);
  emit('pageChange');
}
const currentChange = (val: number) => {
  emit('update:currentPage', val);
  emit('pageChange');
}
</script>
<style scoped>
.text-overflow {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
</style>

页面中使用组件

<template>
  <div>总条数:{{ tbConfig.totalSize }};当前页:{{ tbConfig.current }};每页条数:{{ tbConfig.pageSize }}</div>

  <BaseTable :data="tbConfig.data" :columns="tbConfig.columns" v-model:currentPage="tbConfig.current"
    v-model:pageSize="tbConfig.pageSize" :totalSize="tbConfig.totalSize" @pageChange="pageClick">
    <template #avatar="{ row }">
      这一列用插槽自定义内容{{ row?.avatar }}
    </template>
    <template #op>
      <el-button type="danger">删除</el-button>
    </template>
  </BaseTable>
</template>
<script lang="ts" setup>
import { reactive } from 'vue';
import { BaseTableConfig, TableColumn } from './BaseTable.vue';
import BaseTable from './BaseTable.vue';

const tbConfig: BaseTableConfig = reactive({
  data: [
    { id: 1, name: 'Ahsh', avatar: 'img1.png', ifKey: true },
    { id: 2, name: 'Rjjds', avatar: 'img2.png', ifKey: false },
    { id: 3, name: 'Ukkd特别长长长长长长长长长长的名字', avatar: 'img3.png', ifKey: true },
  ],
  columns: <TableColumn[]>[
    { prop: 'id', label: '序号', width: 100 },
    { prop: 'name', label: '名称', width: 200 },
    { prop: 'avatar', label: '图标', slot: 'avatar', width: 200 },
    { prop: 'ifKey', label: '是否开放', formatter: formatBoolean },
    { label: '操作', slot: 'op' },
  ],
  current: 1,
  pageSize: 10,
  totalSize: 0,
});

function formatBoolean(val: Boolean) {
  return val ? '是' : '否';
}

function pageClick() {
  // TODO监听到当前页或者每页条数变化,重新查询列表
  console.log('get-data');
}
</script>
<style scoped></style>


http://www.kler.cn/news/303075.html

相关文章:

  • ADB 之 logcat 极简小抄(过滤日志、保存日志到文件)
  • C++复习day11
  • 基于人工智能的自动驾驶系统项目教学指南
  • 【C++】STL容器-string的遍历
  • Android10源码刷入Pixel2以及整合GMS
  • 【python】python中非对称加密算法RSA实现原理与应用实战
  • Linux的历史,版本,Linux的环境安装、简单学习4个基本的Linux指令、创建普通用户等的介绍
  • android kotlin 基础复习 继承 inherit
  • 用AI的智慧,传递感恩之心——GPT-4o助力教师节祝福
  • ClickHouse 的底层架构和原理
  • 【最新华为OD机试E卷-支持在线评测】通过软盘拷贝文件(200分)多语言题解-(Python/C/JavaScript/Java/Cpp)
  • 密码测评三级相关项理解
  • 7 递归——206. 反转链表 ★
  • 【Canvas与密铺】正六边形、正方形和正三角形的密铺
  • mysql Field ‘ssl_cipher‘ doesn‘t have a default value的解决
  • Ansible自动化部署kubernetes集群
  • 【鸿蒙】HarmonyOS NEXT星河入门到实战7-ArkTS语法进阶
  • Microsoft SC-100: Microsoft 网络安全架构师
  • DDR3(三)
  • Python中处理非贪婪匹配
  • [linux]GCC G++官方源码国内下载地址汇总
  • 声音克隆工具CosyVoice
  • LeetCode 25. K 个一组翻转链表
  • UE5学习笔记21-武器的射击功能
  • MongoDB创建用户教程
  • Java铸基之路:运算符的深入学习!(上)
  • uni-app--》打造个性化壁纸预览应用平台(三)
  • HTML 转 PDF API 接口
  • 需求分析例题
  • 基于SpringBoot+Vue+MySQL的影院购票系统