1.0.7 • Published 5 months ago

element-plus-table v1.0.7

Weekly downloads
-
License
MIT
Repository
github
Last release
5 months ago

基于 Vue3、Element Plus 开发的一款表格组件,对 Element Plus 的 el-table 进行二次封装

只需要,传如columns,和接口即可把后台的表单搜索项,列表,及分页渲染出了,并支持自定义内容,可以提高开发效率30%左右。

TablePlus 组件上的绑定的所有属性和事件都会通过 v-bind="$attrs" 透传到 el-table 上。 TablePlus 组件内部暴露了 el-table DOM,可通过 TablePlus.value.element.方法名 调用其方法 也就是说你想使用 el-table 的任何属性、事件,目前通过属性透传都能支持。

安装

npm install element-plus-table -S

项目中引入

import { createApp } from 'vue'
import App from './App.vue'
import TablePlus from "element-plus-table"

const app = createApp(App);

app.use(TablePlus)

app.mount('#app')

在项目中使用入门案例

<template>
  <TablePlus
    ref="tablePlus"
    title="列表"
    :columns="columns"
    :request-api="getTableList"
    row-key="articleId"
  ></TablePlus>
</template>

<script setup lang="tsx">
import { ref } from "vue"
const rowItem = {
  articleId: 0,
  title: "文章标题",
  origin: 1,
  publishTime: "2024-09-01 12:00:00",
  publishStatus: 2
}
type rowItemType = typeof rowItem
interface paramsReq {
  pageSize: number
  pageNum: number
}
const tablePlus = ref()
// 模拟获取列表接口
const articleList = (params: paramsReq) => {
  return new Promise((resolve) => {
    const entities: rowItemType[] = []
    for (let i = 0; i < 10; i++) {
      entities.push({
        articleId: i,
        title: "文章标题" + i,
        origin: 1,
        publishTime: "2024-09-01 12:00:00",
        publishStatus: 2
      })
    }
    const ressult = {
      total: 100,
      pageNum: params.pageNum,
      pageSize: params.pageSize,
      list: entities
    }
    setTimeout(() => {
      resolve(ressult)
    }, 1500)
  })
}
const getTableList = (params: paramsReq) => {
  const newParams = JSON.parse(JSON.stringify(params))
  // 请求前参数可以在这里处理
  return articleList(newParams)
}

// 表格配置项
const columns = [
  { type: "index", label: "序号", width: 80 },
  {
    prop: "title",
    label: "文章标题0"
  },
  {
    prop: "title",
    label: "文章标题1",
    search: {
      el: "input",
      props: { maxlength: 30, placeholder: "请输入文章标题1" }
    }
  }
]
</script>

稍微复杂点案例

<template>
  <TablePlus
    ref="tablePlus"
    title="列表"
    :columns="columns"
    :request-api="getTableList"
    :init-param="initParam"
    :pagination="true"
    :data-callback="dataCallback"
    :reset-callback="resetCallback"
    row-key="articleId"
  >
    <!-- 表格 header 按钮 -->
    <template #tableHeader="scope">
      <el-button type="primary" :icon="CirclePlus" class="mb10">新建</el-button>
      <el-button
        type="primary"
        plain
        :disabled="!scope.isSelected"
        class="mb10"
        @click="batchPublish(scope.selectedListIds, 2)"
      >
        批量发布
      </el-button>
      <el-button
        type="danger"
        :icon="Delete"
        plain
        :disabled="!scope.isSelected"
        class="mb10"
        @click="batchDelete(scope.selectedListIds)"
      >
        批量删除
      </el-button>
    </template>
    <!-- 表格操作 -->
    <template #operation="scope">
      <el-button
        type="primary"
        link
        :icon="EditPen"
        @click="openDrawerEdit(scope.row)"
      >
        编辑
      </el-button>
      <el-button type="primary" link :icon="Delete">删除</el-button>
    </template>
  </TablePlus>
</template>

<script setup lang="tsx">
import { ref, reactive } from "vue"
import { CirclePlus, Delete, EditPen } from "@element-plus/icons-vue"
const rowItem = {
  articleId: 0,
  title: "文章标题",
  origin: 1,
  publishTime: "2024-09-01 12:00:00",
  publishStatus: 2
}
type rowItemType = typeof rowItem
interface paramsReq {
  pageSize: number
  pageNum: number
}
const tablePlus = ref()
const initParam = reactive({
  type: "yyy",
  pageSize: 10,
  hotWordList: []
})
// 模拟获取列表接口
const articleList = (params: paramsReq) => {
  return new Promise((resolve) => {
    const entities: rowItemType[] = []
    for (let i = 0; i < 10; i++) {
      entities.push({
        articleId: i,
        title: "文章标题" + i,
        origin: 1,
        publishTime: "2024-09-01 12:00:00",
        publishStatus: 2
      })
    }
    const ressult = {
      total: 100,
      pageNo: params.pageNum,
      pageSize: params.pageSize,
      entities
    }
    setTimeout(() => {
      resolve(ressult)
    }, 1500)
  })
}
const dataCallback = (data: any) => {
  data?.entities.forEach((item: any) => {
    item.mechanismValue = [item.category, item.column]
  })
  return {
    list: data?.entities,
    total: data.total,
    pageNum: data.pageNo,
    pageSize: data.pageSize
  }
}
const getTableList = (params: paramsReq) => {
  const newParams = JSON.parse(JSON.stringify(params))
  // 请求前参数可以在这里处理
  return articleList(newParams)
}
// 批量删除用户信息
const batchDelete = async (articleIds: string[]) => {
  console.log("articleIds", articleIds)
  // await fetchAPI()
  tablePlus.value?.clearSelection()
  tablePlus.value?.getTableList()
}
const batchPublish = async (articleIds: string[], status: number) => {
  console.log("articleIds: string[], status: number", articleIds, status)
  // await fetchAPI()
  tablePlus.value?.clearSelection()
  tablePlus.value?.getTableList()
}
// 表格配置项
const columns = [
  { type: "selection", fixed: "left", width: 80 },
  { type: "index", label: "序号", width: 80 },
  {
    prop: "title",
    label: "文章标题0"
  },
  {
    prop: "title",
    label: "文章标题",
    search: {
      el: "input",
      props: { maxlength: 30, placeholder: "请输入文章标题" }
    }
  },
  {
    prop: "title",
    label: "文章标题2",
    search: {
      el: "input",
      order: 10,
      props: { maxlength: 30, placeholder: "请输入文章标题2" }
    }
  },
  {
    prop: "title",
    label: "文章标题3",
    isShow: false,
    search: {
      el: "input",
      order: 1,
      props: { placeholder: "请输入文章标题3" }
    }
  },
  {
    prop: "origin",
    label: "数据来源",
    width: 160,
    enum: [
      {
        label: "文章库",
        value: 1
      },
      {
        label: "自建新增 ",
        value: 2
      }
    ],
    search: { el: "tree-select", props: { filterable: true } }
  },

  {
    prop: "publishTime",
    label: "发布时间",
    width: 180,
    render: (scope) => {
      return <div>{scope.row.publishTime || "- -"}</div>
    }
  },

  {
    prop: "publishStatus",
    label: "是否发布",
    width: 160,
    enum: [
      {
        label: "已发布",
        value: 2
      },
      {
        label: "未发布",
        value: 1
      }
    ],
    search: { el: "tree-select", props: { filterable: true } },
    render: (scope) => {
      return (
        <>
          <el-switch
            model-value={scope.row.publishStatus}
            active-text={scope.row.publishStatus === 2 ? "已发布" : "未发布"}
            active-value={2}
            inactive-value={1}
            onClick={doPublish}
          />
        </>
      )
    }
  },
  { prop: "operation", label: "操作", fixed: "right", width: 200 }
]
const resetCallback = () => {
  console.log("resetCallBack")
  initParam.hotWordList = []
  tablePlus.value?.getTableList()
}
// 上架
const doPublish = async (params: any) => {
  console.log("doPublish", params)
  // await fetchAPI()
  tablePlus.value?.getTableList()
}
const openDrawerEdit = async (row: Partial<any>) => {
  console.log(row)
}
</script>
<style scoped>
.mb10 {
  margin-bottom: 10px;
}
</style>

表格中每一项都可以都可以通过render可使用 tsx 组件自定义渲染

<script setup lang="tsx">
const columns = reactive<ColumnProps<User.ResUserList>[]>([{
    prop: "publishTime",
    label: "发布时间",
    width: 180,
    render: (scope) => {
      return <span>{scope.row.publishTime || "- -"}</span>
    }
  },
];
</script>

表格搜索项可使用 tsx 组件自定义渲染

<script setup lang="tsx">
const columns = reactive<ColumnProps<User.ResUserList>[]>([
   {
    prop: "score",
    label: "分数",
    search: {
      // 自定义 search 组件
      render: ({ searchParam }) => {
        return (
          <div>
            <el-input vModel_trim={searchParam.minAge} placeholder="最小分数"/>
            <span>-</span>
            <el-input vModel_trim={searchParam.maxAge} placeholder="最大分数" />
          </div>
        );
      }
    }
  },
];
</script>

也就是说search 表单组件我们 可以自定义任意组件放上面,并且可以在请求发出前,对参数进行特殊处理

TablePlus 属性

参数类型是否必填默认值描述
columnsColumnProps[]TablePlus 组件会根据此字段渲染搜索表单与表格列(支持动态更新)
request-apiFunction-获取表格数据的请求 API
dataArray-静态 tableData 数据(支持分页),若存在则不会使用 request-api 返回的 data
data-callbackFunction-后台返回数据的回调函数,可对后台返回数据进行处理
reset-callbackFunction-用户点击重置按钮的回调函数,可对搜索表单进行参数进行特殊处理
paginationBoolean-是否显示分页组件:pagination 为 false 后台返回数据应该没有分页信息 和 list 字段,data 就是 list 数据
initParamObject{}表格请求的初始化参数,该值变化会重新请求表格数据
rowKeyString'id'当表格数据多选时,所指定的 id
tableSearchColumnsColumnProps[]TablePlus 组件会根据此字段渲染搜索表单支持动态更新)有这个参数后就会上面表单就会用这个参数去渲染
request-errorFunction-表格 API 请求错误监听|

Column 配置(ColumnProps 属性)

参数类型是否必填默认值描述
typeString-对应列的类型("index""selection""radio""expand""sort"))
tagBooleanfalse前单元格值是否为标签展示,可通过 enum 数据中 tagType 字段指定 tag 类型
isShowBooleantrue当前列是否显示在表格内(只对 prop 列生效)
searchSearchProps-搜索项配置,详情见 SearchProps
enumArrayFunction-可格式化单元格内容,还可以作为搜索框的下拉选项(字典可以为 API 请求函数,内部会自动执行)
fieldNamesObject-指定 label && value && children 的 key 值
headerRenderFunction-自定义表头内容渲染(tsx 语法、h 语法)
renderFunction-自定义表头内容渲染(tsx 语法、h 语法)

搜索项 配置(SearchProps):

参数类型是否必填默认值描述
elString-当前项搜索框的类型,支持:input、input-number、select、select-v2、tree-select、cascader、date-picker、time-picker、time-select、switch、slider)
labelStringString-当搜索项 label,如果不指定默认取 column 的 label
propsObject-根据 element plus 官方文档来传递,通过属性透传将 search.props 属性全部透传到每一项搜索组件上,所以我们支持 input、select、tree-select、date-packer、time-picker、time-select、switch 大部分属性
keyString-当搜索项 key 不为 prop 属性时,可通过 key 指定
orderNumber-搜索项排序(从小到大)
keyString-当搜索项 key 不为 prop 属性时,可通过 key 指定
defaultValueAny-搜索项默认值(该值重置时会重置回初始值)
renderFunction-自定义搜索内容渲染(tsx 语法、h 语法)

TablePlus 的方法:

参数描述
elementel-table 实例,可以通过TablePlus.value.element.***()来调用 el-table 的所有方法)
getTableList获取、刷新表格数据的方法(携带所有参数)
tableData当前页面所展示的数据
pageable当前表格的分页数据
searchParam所有的搜索参数,不包含分页
searchInitParam所有的搜索初始化默认的参数
search表格查询方法,相当于点击搜索按钮
reset重置表格查询参数,相当于点击重置按钮
handleSizeChange表格每页条数改变触发的事件
handleCurrentChange表格当前页改变触发的事件
clearSelection清空表格所选择的数据
enumMap当前表格使用的所有字典数据(Map 数据结构)
isSelected表格是否选中数据
selectedList表格选中的数据列表
selectedListIds表格选中的数据列表的id

如 在组件中 tablePlus.value?.getTableList() 即可获取最新列表数据

TablePlus 插槽:

插槽描述
tableHeader自定义表格头部左侧区域的插槽,一般情况该区域放操作按钮
toolButton自定义表格头部左右侧侧功能区域的插槽
empty当表格数据为空时自定义的内容
pagination分页组件插槽
1.0.7

5 months ago

1.0.6

5 months ago

1.0.5

5 months ago

1.0.4

5 months ago

1.0.3

5 months ago

1.0.2

5 months ago