el-data-table
使用axios
自动发送请求,支持树形结构,支持分页,支持自定义查询, 自定义操作列, 让 RESTful 风格的 CRUD 更简单 👏
auto requesting by axios
, supports pagination, tree data structure, custom search, custom operation column, makes rest api easily 👏
Table of Contents
Introduction
CRUD
el-data-table 就是为了解决业务问题而生的,故而封装了 CRUD 的逻辑在里面。
以用户接口示例,设其相对路径为:
/api/v1/users
则其 restful CRUD 接口如下:
- 查询
GET /api/v1/users?page=1&size=10
- 新增
POST /api/v1/users
- 修改(编辑)
PUT /api/v1/users/:id
- 删除
DELETE /api/v1/users/:id
则只需要使用以下代码,即可完成 CRUD 功能
<template> <el-data-table v-bind="tableConfig"></el-data-table></template>
<script> { return tableConfig: url: '/example/users' columns: prop: 'name' label: '用户名' searchForm: $type: 'input' $id: 'name' label: '用户名' $el: placeholder: '请输入' form: $type: 'input' $id: 'name' label: '用户名' $el: placeholder: '请输入' rules: required: true message: '请输入用户名' trigger: 'blur' }</script>
效果如下:
- 查询
- 新增
- 修改
- 删除
数据驱动
把 template 的内容移动到 script 中, 意味着 template 可以精简,js 可以抽取出来,方便复用;同时,js 里的数据其实就是一段 json,这也让代码生成工具有了用武之地。
WHY
为什么要在 element-ui 的 el-table 的基础上封装一个 el-data-table?
我常听到有以下几种声音:
- el-table 已可以覆盖大部分场景,暂无扩展需求
- 封装了这么多东西,耦合太严重了
- 涉及过多的业务逻辑,有点僵化,业务操作还是交给开发者去处理
首先 el-table 的确很灵活,只不过,在实现分页请求的时候,仅有 el-table 还不够,还需要组合 el-pagination 组件来实现。而分页处理的内容大多都是重复的,如果不封装,只会产生冗余的代码。
而中后台太多都是 CRUD 的操作,结合 restful API,使用得只传一个 url 让组件做 CRUD 成为了可能。
其次,很多有经验的“老手”觉得组件越灵活越好。
但对于经验尚浅的“新手”,他们并不熟悉常见的业务场景,对一些基本操作,如果表单校验,空格过滤,添加 loading,异常处理,他们只会漏掉,而这正是产生 bug 的源头。
对于一线的业务开发人员而言,面对做不完的业务,其实他们并不想去处理重复的业务逻辑,他们只想解放双手,早点下班。
正是在这样的背景下,产生了 el-data-table。
Feature
- 只需进行 json 配置,即可实现 restful 风格的 CRUD 四个接口的对接
- 支持表格内展示树形结构数据(该功能 element-ui 官方是不支持的)
- 自带分页逻辑
- 可扩展自定义列按钮,以及自定义操作函数
- 支持分页查询后,点击详情再返回,恢复上一次的查询状态
Demo
Install
encourage using yarn to install
yarn add el-data-table
Quick Start
global register component
this is for minification reason: in this way building your app,
webpack or other bundler just bundle the dependencies into one vendor for all pages which using this component,
instead of one vendor for one page
// register component and loading directive VueVueVueVueVueVueVueVueVueVue // to show confirm before deleteVueprototype$confirm = MessageBoxconfirm // show tipsVueprototype$message = Message // if the table component cannot access `this.$axios`, it cannot send requestVueprototype$axios = axios
template
<template> <el-data-table></el-data-table></template>
Example
basic
suppose the api response looks like this:
"code": 0 "msg": "ok" "payload": "content": // the data to render "totalElements": 2 // total count
we get setting
<el-data-table dataPath="payload.content" totalPath="payload.totalElement"></el-data-table>
that's the default setting, you can get your custom setting according to your api
now I'll show you more code example, here we go🚴
url and columns
<!-- template --><el-data-table :url="url" :columns="columns"></el-data-table>
// script { return url: 'https://easy-mock.com/mock/5b586c9dfce1393a862d034d/example/img' // full attributes of columns see: http://element.eleme.io/#/zh-CN/component/table#table-column-attributes columns: prop: 'code' label: '品牌编号' prop: 'name' label: '品牌名称' prop: 'alias' label: '品牌别名' prop: 'logoUrl' label: '品牌Logo' width: '150px' prop: 'status' label: '状态' rowstatus === 'normal' ? '启用' : '禁用' }
if
url
change, the table will reload
new/edit form
this will show new or edit form, when you click new or edit button
<!-- template --><el-data-table :url="url" :columns="columns" :form="form"></el-data-table>
// scriptform: $type: 'select' $id: 'backendFramework' label: '后端框架' rules: required: true message: '请选择后端框架' trigger: 'blur' $options: 'DUBBO' 'HSF' $el: placeholder: '请选择' $type: 'input' $id: 'name' label: '名称' rules: required: true message: '请输入名称' trigger: 'blur' v && v $el: placeholder: '请输入'
searchForm
<!-- template --><el-data-table :url="url" :columns="columns" :form="form" :searchForm="searchForm"></el-data-table>
// scriptsearchForm: $el: placeholder: '请输入' label: '用户名' $id: 'username' $type: 'input' $el: placeholder: '请输入' label: '全名' $id: 'fullname' $type: 'input' $el: placeholder: '请输入' label: 'email' $id: 'email' $type: 'input'
formatter
<!-- template --><el-data-table :url="url" :columns="columns">
// scriptcolumns: // formatter: you can return the jsx syntax prop: 'imageUrl' label: '商品图片' <div> <img src=rowimageUrl onClick=thishandlePreviewUrl /> </div>
selection
<!-- template --><el-data-table :url="url" :columns="columns"></el-data-table>
// scriptcolumns: // type: 'selection' will show checkbox // see http://element.eleme.io/#/zh-CN/component/table#table-column-attributes type: 'selection' index > 0 prop: 'code' label: '品牌编号' prop: 'name' label: '品牌名称' prop: 'alias' label: '品牌别名' prop: 'logoUrl' label: '品牌Logo' width: '150px' prop: 'status' label: '状态' rowstatus === 'normal' ? '启用' : '禁用'
headerButtons
buttons on the top of the table
attention: click function called
atClick
<!-- template --><el-data-table :url="url" :columns="columns" :headerButtons="headerButtons"></el-data-table>
// script// more attribute see: https://femessage.github.io/el-data-table/headerButtons: text: '批量导出' selectedlength == 0 // selected 是选中行所组成的数组 { let ids = selected }
extraButtons
extra buttons in operation column
attention: click function called
atClick
<!-- template --><el-data-table :url="url" :columns="columns" :extraButtons="extraButtons"></el-data-table>
// script// more attribute see: https://femessage.github.io/el-data-table/extraButtons: type: 'primary' text: '跳转' // row 是单行的数据 { return Promise }
beforeSearch
This function will invoke after clicking search button. It should return promise, if it resolve, search will execute; if it reject, search won't execute.
<!-- template --><el-data-table :url="url" :columns="columns" :searchForm="searchForm" :beforeSearch="beforeSearch"></el-data-table>
// scriptreturn url: '' columns: prop: 'name' label: '用户名' prop: 'createdBy' label: '创建人' prop: 'userInfo.createTime' label: '创建时间' searchForm: $type: 'input' $id: 'name' label: '用户名' $el: placeholder: '请输入用户名' // rules: [{required: true, trigger: 'blur', whitespace: true}] { thisurl = 'https://xxx' return Promise }
beforeConfirm
在新增/修改弹窗点击确认, 并完成表单 form 表单校验后调用,需要返回 Promise. 如果 resolve, 则会发送新增/修改请求; 如果 reject, 则不会发送新增/修改请求. 参数: (data, isNew) data 为表单数据, isNew true 表示是新增弹窗, false 为 编辑弹窗
<el-data-table :beforeConfirm="beforeConfirm"></el-data-table>
{ console if isNew return Promise else return Promise }
customQuery
查询时,在 url 上添加额外的参数
customQuery: type: 1
假设url
参数配置为/api/v1/users
则实际查询请求为:/api/v1/users?type=1
extraParams
新增/修改请求时,在 body 里添加额外的参数
extraParams: version: 0 isTree: false
onNew
默认情况下, 新增的请求格式是 POST url body 当默认新增方法不满足需求时可使用 onNew, 需要返回 promise 参数(data, row) data 是 form 表单的数据, row 是当前行的数据, 只有 isTree 为 true 时, 点击操作列的新增按钮才会有值
<el-data-table :onNew="onNew"></el-data-table>
{ console return Axios}
onEdit
默认情况下, 修改的请求格式是 PUT url/id body 点击修改按钮时的方法, 当默认修改方法不满足需求时可使用 onEdit, 需要返回 promise 参数(data, row) data 是 form 表单的数据, row 是当前行的数据
<el-data-table :onEdit="onEdit"></el-data-table>
{ console return Axios}
onDelete
默认情况下:
- 删除单个的请求格式是 DELETE url/id
- 删除多个的请求格式是 DELETE url/id,id,id
当不满足需求时, 可以使用 onDelete, 自定义删除方法, 返回 promise
<el-data-table onDelete="onDelete"></el-data-table>
// 多选时, 参数为selected, 代表选中的行组成的数组 { return Axios} // 非多选时参数为row, 代表单行的数据 { return Axios}
Reference
- form rules detail see async-validator
- el-input enter to submit
- html spec form submission
- What_is_a_URL
- History_API
- encodeURIComponent
- RegExp
- 从 vue-router 看前端路由的两种实现
- peer-dependencies