TablePage 使用
render
函数渲染组件,跳过编译过程,效率更高、性能更好, 可维护性更强!它将日常开发中最常用的表格列表页面完整的封装成了一个组件,包含了可能遇到的各种功能,通过使用时传递的配置信息生成页面,若已有的功能或样式不能满足的部分,也可以通过插槽的形式自定义编写
最近更新日期: 2022-07-14, 最新稳定版: v1.2.2, 详情可以参考 更新日志
在终端命令行使用指令安装依赖,然后按照下一步骤引入、注册全局组件使用
npm install tablepage-vuejs --save
如果项目中没有使用 Element UI,则也需要一并引入
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import tablePage from 'tablepage-vuejs'
Vue.config.productionTip = false
Vue.use(ElementUI)
Vue.use(tablePage)
/* eslint-disable no-new */
new Vue({
el: '#app',
components: { App },
template: '<App/>'
})
目前可以通过 unpkg.com/tablepage-vuejs 获取到所有版本的资源,在页面上引入 js 文件即可开始使用。
<script src="https://unpkg.com/[email protected]/dist/table-page.min.js"></script>
这是最基本的使用,至少得传入
title
、tableData
以及tableColumnSet
,分别表示页面标题
、数据源
和每一列的配置信息
<template>
<table-page title="高质量人类" :tableData="tableData"></table-page>
</template>
<script type="text/ecmascript-6">
export default {
provide() {
return {
tableColumnSet: [
{
prop: 'name',
label: '姓名'
},
{
prop: 'birthday',
label: '出生日期',
},
{
prop: 'sex',
label: '性别',
},
{
prop: 'phone',
label: '联系电话'
},
{
prop: 'hobbies',
label: '爱好'
},
{
prop: 'education',
label: '学历'
},
{
prop: 'occupation',
label: '职业'
},
{
prop: 'address',
label: '联系地址'
}
],
}
},
data() {
return {
tableData: [
{
name: '大山',
birthday: '2003-03-29',
sex: '男',
phone: '18888888888',
hobbies: '动漫',
education: '本科',
occupation: '程序员',
address: '广东省 广州市 白云区'
}
]
}
}
}
</script>
通过传入更多属性以展示一个功能丰富的表格页面, 你可以在下方代码区修改代码进行调试,数据来源
Easy Mock
参考文档: https://mock.ogliu.com
<template>
<div id="tablePage" style="min-width: 800px;">
<table-page
title="高质量人类"
subtitle="让天下没有难找的对象"
:tableData="tableData"
@currentChange="currentChange"
@sizeChange="sizeChange"
@onSearch="onSearch"
@onClear="onClear"
backButton
@goBack="goBack"
:loading="loading">
<template slot="birthday" slot-scope="scope">
<el-date-picker value-format="yyyy-MM-dd" size="small" v-model="birthday" type="date" placeholder="选择日期"></el-date-picker>
</template>
<template slot="clear">
<el-dropdown split-button type="primary" size="small">
更多名单
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>凶猛的小萝莉</el-dropdown-item>
<el-dropdown-item>沧伤的小正太</el-dropdown-item>
<el-dropdown-item>娇萌的怪叔叔</el-dropdown-item>
<el-dropdown-item>恐怖的御姐姐</el-dropdown-item>
<el-dropdown-item>性感的老阿姨</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
<template slot="names" slot-scope="scope">
<div style="color: #409eff">{{scope.row.name}}</div>
</template>
</table-page>
</div>
</template>
<script type="text/ecmascript-6">
export default {
data(){
return {
birthday: '',
tableData: [],
pagination: {},
loading: false,
search: {}
}
},
provide() {
return {
floatButtonSet: [
{
renderType: 'button',
text: '新增高质量人类',
type: 'primary',
onClick: this.added
},
{
renderType: 'slot',
slot: 'clear'
},
{
renderType: 'dropdown',
text: '导出数据',
menuSet: [
{
text: '导出高质量男孩',
onClick: this.leadingOutBoys
},
{
text: '导出高质量女孩',
onClick: this.leadingOutGirls
}
],
},
{
renderType: 'button',
text: '黑名单',
disabled: true,
type: 'info',
onClick: this.blacklist
}
],
searchBarSet: [
{
renderType: 'input',
label: '姓名',
width: 240,
key: 'name',
placeholder: '请输入姓名'
},
{
renderType: 'slot',
label: '出生日期',
slot: 'birthday',
},
{
renderType: 'select',
label: '学历',
placeholder: '请选择学历',
key: 'education',
options: [
{
value: '专科',
label: '专科'
}, {
value: '本科',
label: '本科'
}, {
value: '硕士',
label: '硕士'
}, {
value: '博士',
label: '博士'
}
]
}
],
tableColumnSet: [
{
renderType: 'slot',
slot: 'names',
renderHeader: this.renderHeader
},
{
prop: 'birthday',
label: '出生日期',
},
{
prop: 'sex',
label: '性别',
},
{
prop: 'phone',
label: '联系电话'
},
{
prop: 'hobbies',
label: '爱好'
},
{
prop: 'education',
label: '学历'
},
{
prop: 'occupation',
label: '职业'
},
{
prop: 'address',
minWidth: 200,
label: '联系地址'
},
{
label: '操作',
renderType: 'button',
maximum: 2,
handleButtonSet: [
{
content: '编辑',
icon: 'el-icon-edit',
type: 'primary',
event: 'doEdit',
// 如果当前行的 name 值不为大山,则显示按钮
isShow: (item) => item.name !== '大山'
},
{
content: '删除',
icon: 'el-icon-delete',
type: 'danger',
event: 'doDel'
}
]
}
],
paginationSet: () => this.pagination
}
},
mounted() {
// 请求接口获取列表数据
this.getData()
},
methods: {
// 自定义表头
renderHeader(createElement, { column }) {
return createElement('span', [
createElement('span', ['姓名' + ' ']),
createElement('el-popover', {
props: {
placement: 'top',
trigger: 'hover',
popperClass: 'titshowTip'
}}, [createElement('span',
['数据来源于 Easy Mock']),
createElement('span', {
slot: 'reference',
'class': { 'el-icon-question': true }
})
])
]
)
},
// 请求接口获取列表数据
getData(page = 1, pageSize = 10, search = {}) {
this.loading = true
// 模拟接口
axios.get('https://mock.ogliu.com/mock/618484ed957ff105d1b54bad/api/list', {
params: { page, pageSize, ...search }
}).then(response => {
this.tableData = response.data.data
this.pagination = {
size: pageSize,
total: response.data.meta.pagination.total,
current: response.data.meta.pagination.current_page
}
this.loading = false
}).catch(function (error) {
console.log(error)
})
},
// 点击搜索按钮
onSearch(search) {
this.getData(1, this.pagination.size, Object.assign({birthday: this.birthday}, search))
},
onClear() {
this.birthday = ''
},
// 当前页码改变
currentChange(page) {
this.getData(page, this.pagination.size, this.search)
},
// 每页展示数量改变
sizeChange(size) {
this.pagination.size = size
this.getData(1, size, this.search)
},
goBack() {
console.log('点击了返回按钮')
},
doEdit(row, index) {
console.log('点击了编辑按钮')
},
doDel(row, index) {
console.log('点击了删除按钮')
},
added() {
console.log('新增高质量人类名单')
},
blacklist() {
console.log('点击了黑名单')
},
leadingOutBoys() {
console.log('导出高质量男孩名单')
},
leadingOutGirls() {
console.log('导出高质量女孩名单')
}
}
}
</script>
下面将详细介绍组件的每一个
prop
、provide
、event
的使用, 建议按顺序阅读
用于展示页面标题,必传属性,每个页面都应该有一个标题
- 传入方式:
Prop
- 类型:
String
- 必传:
是
<template>
<table-page title="高质量人类"></table-page>
</template>
用于展示副标题,可选属性,不需要不传即可
- 传入方式:
Prop
- 类型:
String
- 必传:
否
<template>
<table-page title="高质量人类" subtitle="让天下没有难找的对象"></table-page>
</template>
通过
接口
从后端获取的数据源,用于表格展示的数据,和tableColumnSet
搭配使用
- 传入方式:
Prop
- 类型:
Array
,对象数组
,每个元素都应该是一个对象,而每个对象表示每行数据 - 必传:
是
<template>
<table-page title="高质量人类" :tableData="tableData"></table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: [
{
name: '大山',
birthday: '2003-03-29',
sex: '男',
phone: '18888888888',
hobbies: '动漫',
education: '本科',
occupation: '程序员',
address: '广东省 广州市 白云区'
}
]
}
}
}
</script>
通过注入的方式对表格每列数据做配置,
tableColumnSet
只是一个容器,用于存放所有的列
的配置信息
- 传入方式:
Provide
- 类型:
Array
,对象数组
,每个元素都应该是一个对象,而每个对象表示每列数据的配置信息 - 必传:
是
<template>
<table-page title="高质量人类" :tableData="tableData"></table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: [
{
name: '大山',
birthday: '2003-03-29',
sex: '男',
phone: '18888888888',
hobbies: '动漫',
education: '本科',
occupation: '程序员',
address: '广东省 广州市 白云区'
}
]
}
},
provide() {
return {
tableColumnSet: [
{
prop: 'name',
label: '姓名'
},
{
prop: 'birthday',
label: '出生日期',
},
{
prop: 'sex',
label: '性别',
},
{
prop: 'phone',
label: '联系电话'
},
{
prop: 'hobbies',
label: '爱好'
},
{
prop: 'education',
label: '学历'
},
{
prop: 'occupation',
label: '职业'
},
{
prop: 'address',
label: '联系地址'
}
]
}
}
}
</script>
这里的
tableColumn
并非真的有这个属性,而是代指tableColumnSet
的每个子元素、表示的是每一列的具体配置信息,这里的每个子元素之间的顺序在页面上展示的顺序对应,例如: 我希望在第 3 列展示性别
,那么就将性别
相关的配置放在第 3 个子元素位置。
目前表格列的类型分为三种: 普通列
、操作按钮展示列
、自定义列
,上述展示的都属于 普通列
。
- 类型:
String
- 必传:
否
- 可选值:
slot(插槽、自定义列)
、button(操作按钮展示、末位列)
,不传则默认是普通列
<template>
<table-page title="高质量人类" :tableData="tableData"></table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: [],
provide() {
return {
tableColumnSet: [
{
label: '姓名',
prop: 'name'
},
{
label: '自定义列',
renderType: 'slot'
},
{
label: '操作',
renderType: 'button'
}
]
}
}
}
}
}
</script>
- 类型:
String
- 必传:
否
<template>
<table-page title="高质量人类" :tableData="tableData"></table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: [],
provide() {
return {
tableColumnSet: [
{
label: '姓名'
}
]
}
}
}
}
}
</script>
有时候表头比较特殊,光展示文本不满足需求,那么就可以不传 label
,使用 renderHeader
自定义表头,它接收一个 render
函数,作为表头渲染
- 类型:
function
- 必传:
否
<template>
<table-page title="高质量人类" :tableData="tableData"></table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: [
{
name: '大山'
}
],
provide() {
return {
tableColumnSet: [
{
prop: 'name',
renderHeader: this.renderHeader
}
]
}
},
methods: {
renderHeader(createElement, { column }) {
return createElement('span', [
createElement('span', ['姓名']),
createElement('el-popover', {
props: {
placement: 'top',
trigger: 'hover',
popperClass: 'titshowTip'
}}, [createElement('span',
['自定义表头']),
createElement('span', {
slot: 'reference',
'class': { 'el-icon-question': true }
})
])]
)
}
}
}
}
}
</script>
只作用于 普通列
,因为 自定义列
通过插槽渲染字段,而操作列不需要渲染字段,它应该和 tableData
对应,例如我希望第一列展示 姓名
,则需要找到 tableData
里 姓名
对应的字段赋值给 prop
- 类型:
String
- 必传:
普通列必传
<template>
<table-page title="高质量人类" :tableData="tableData"></table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: [
{
name: '大山'
}
],
provide() {
return {
tableColumnSet: [
{
label: '姓名',
prop: 'name'
}
]
}
}
}
}
}
</script>
对应列的宽度,可以传数值类型或者字符串类型的数字,带单位(px)也能识别,推荐传数值就好。
- 类型:
String || Number
- 必传:
否
<template>
<table-page title="高质量人类" :tableData="tableData"></table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: [
{
name: '大山'
}
],
provide() {
return {
tableColumnSet: [
{
label: '姓名',
prop: 'name',
width: 200
}
]
}
}
}
}
}
</script>
对应列的最小宽度,可以传数值类型或者字符串类型的数字,带单位(px)也能识别,推荐传数值就好。
- 类型:
String || Number
- 必传:
否
<template>
<table-page title="高质量人类" :tableData="tableData"></table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: [
{
name: '大山'
}
],
provide() {
return {
tableColumnSet: [
{
label: '姓名',
prop: 'name',
minWidth: 200
}
]
}
}
}
}
}
</script>
在某些时候,我们预设的表格列不满足需求,就需要使用到插槽来实现自定义列, 在接收 slot
字段之前,务必先将 renderType
的值设置为 slot
- 类型:
String
- 必传:
否
使用步骤:
- 确认需要插入列的位置,例如需要在第 2 列使用自定义列,那么就需要在
tableColumnSet
的第 2 个子元素配置插槽。 - 设置
renderType
的值为slot
。 - 设置
slot
对应的名称,它将与template
的slot
字段对应。 - 在组件体内开启
template
,设置模板名称。 - 编写自定义内容。
<template>
<table-page title="高质量人类" :tableData="tableData">
<!-- 4. 在组件体内开启 template,注意它的 slot 属性值,必须与第上一步设置的名称一致 -->
<template slot="sex" slot-scope="scope">
<!-- 5. 编写自定义的内容 -->
<div style="color: #409eff">{{scope.row.name}}</div>
</template>
</table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: [
{
name: '大山'
}
],
provide() {
return {
tableColumnSet: [
{
label: '姓名',
prop: 'name',
minWidth: 200
},
{
// 1. 确认位置,在此处开启插槽列的配置
label: '性别',
renderType: 'slot', // 2. 设置 renderType 的值为 slot, 告诉组件要以插槽的模式来渲染
slot: 'sex', // 3. 设置当前插槽列对应的模板名称
}
]
}
}
}
}
}
</script>
在表格末尾一列可以设置 操作按钮集合
列,首先需要把 renderType
的值设置为 button
,然后它将接收一个 handleButtonSet
字段,它是一个对象数组,数组内每一个对象代表着一个按钮的配置,为了方便理解,下面我将以 handleButton
来表示这个对象,当然它的顺序也对应着页面上渲染的顺序,与 tableColumnSet
一样,handleButtonSet
只是一个容器,按钮的具体配置都落实在它的子元素 handleButton
上,操作按钮
可以获取当前行的数据做对应的操作,整个操作列在页面宽度不够的时候会固定展示在右侧。
- 类型:
Number
- 必传:
否
<template>
<table-page title="高质量人类" :tableData="tableData"></table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: [
{
name: '大山'
}
],
provide() {
return {
tableColumnSet: [
{
label: '姓名',
prop: 'name',
minWidth: 200
},
{
label: '操作',
renderType: 'button',
maximum: 3,
handleButtonSet: [
{
content: '编辑',
icon: 'el-icon-edit',
type: 'primary',
event: 'doEdit',
// 如果当前行的 name 值为大山,则显示按钮
isShow: (item) => item.name === '大山'
}
]
}
]
}
},
methods: {
doEdit(row, index) {
console.log('点击了编辑按钮')
}
}
}
}
}
</script>
这里的
handleButton
并非真的有这个属性,而是代指handleButtonSet
的每个子元素,表示的是每一个操作按钮的配置信息。
按钮提示文本,鼠标滑动到按钮上浮现的提示文字
- 类型:
String
- 必传:
是
<template>
<table-page title="高质量人类" :tableData="tableData"></table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: [
{
name: '大山'
}
],
provide() {
return {
tableColumnSet: [
{
label: '姓名',
prop: 'name',
minWidth: 200
},
{
label: '操作',
renderType: 'button',
handleButtonSet: [
{
content: '编辑'
}
]
}
]
}
}
}
}
}
</script>
字体图标名称, Element UI
图标。
- 类型:
String
- 必传:
否
<template>
<table-page title="高质量人类" :tableData="tableData"></table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: [
{
name: '大山'
}
],
provide() {
return {
tableColumnSet: [
{
label: '姓名',
prop: 'name',
minWidth: 200
},
{
label: '操作',
renderType: 'button',
handleButtonSet: [
{
content: '编辑',
icon: 'el-icon-edit'
}
]
}
]
}
}
}
}
}
</script>
svg 图标配置,它与 icon
二选一即可,基于插件 svg-vuejs
, 它接收一个对象,对象内部接收所有插件提供的参数,详情参考文档: https://svg.ogliu.com
- 类型:
Object
- 必传:
否
<template>
<table-page title="高质量人类" :tableData="tableData"></table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: [
{
name: '大山'
}
],
provide() {
return {
tableColumnSet: [
{
label: '姓名',
prop: 'name',
minWidth: 200
},
{
label: '操作',
renderType: 'button',
handleButtonSet: [
{
content: '编辑',
svg: {
name: 'edit',
width: '16',
height: '16',
color: '#FFF'
}
}
]
}
]
}
}
}
}
}
</script>
按钮的颜色风格, 沿用 Element ui
按钮风格。
- 类型:
String
- 必传:
否
- 可选值:
primary
,success
,info
,warning
,danger
, 不传参数则为黑白按钮。
<template>
<table-page title="高质量人类" :tableData="tableData"></table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: [
{
name: '大山'
}
],
provide() {
return {
tableColumnSet: [
{
label: '姓名',
prop: 'name',
minWidth: 200
},
{
label: '操作',
renderType: 'button',
handleButtonSet: [
{
content: '编辑',
icon: 'el-icon-edit',
type: 'primary'
}
]
}
]
}
}
}
}
}
</script>
点击按钮触发的回调函数,需要注意的是这里接收的是回调函数的函数名,而并非函数体,对应的回调函数应该写在 methods
中,它有两个预设参数 row
、index
可以获取当前行的数据和索引
- 类型:
String
- 必传:
否
<template>
<table-page title="高质量人类" :tableData="tableData"></table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: [
{
name: '大山'
}
],
provide() {
return {
tableColumnSet: [
{
label: '姓名',
prop: 'name',
minWidth: 200
},
{
label: '操作',
renderType: 'button',
handleButtonSet: [
{
content: '编辑',
icon: 'el-icon-edit',
type: 'primary',
event: 'doEdit'
}
]
}
]
}
},
methods: {
doEdit(row, index) {
console.log('点击了编辑按钮')
}
}
}
}
}
</script>
当前按钮是否显示,可用于做权限限制,这里接收返回值为 Boolean
布尔值的回调函数, 你可以通过回调函数预设的参数 item
获取 当前行数据
。
- 类型:
function
- 必传:
否
<template>
<table-page title="高质量人类" :tableData="tableData"></table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: [
{
name: '大山'
}
],
provide() {
return {
tableColumnSet: [
{
label: '姓名',
prop: 'name',
minWidth: 200
},
{
label: '操作',
renderType: 'button',
handleButtonSet: [
{
content: '编辑',
icon: 'el-icon-edit',
type: 'primary',
event: 'doEdit',
// 如果当前行的 name 值为大山,则显示按钮
isShow: (item) => item.name === '大山'
}
]
}
]
}
},
methods: {
doEdit(row, index) {
console.log('点击了编辑按钮')
}
}
}
}
}
</script>
用于配合项目中的自定义指令 v-permission
,若项目中没有该指令,则无效。
- 类型:
Array
||String
- 必传:
否
在头部右侧新增浮动按钮,可以配置不同的
文本内容
,类型
、风格(颜色)
、事件
等等,暂时可以配置普通按钮
和下拉菜单按钮
,如果不满足需求,可利用插槽自定义按钮。
- 传入方式:
Provide
- 类型:
Array
,对象数组
,每个元素都应该是一个对象,而每个对象表示每个浮动按钮
的配置信息 - 必传:
否
<template>
<table-page title="高质量人类" :tableData="tableData"></table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: []
}
},
provide() {
return {
floatButtonSet: [
{
renderType: 'button',
text: '新增高质量人类',
type: 'primary',
onClick: this.added
}
],
tableColumnSet: [
{
prop: 'name',
label: '姓名'
},
{
prop: 'birthday',
label: '出生日期',
},
{
prop: 'sex',
label: '性别',
},
{
prop: 'phone',
label: '联系电话'
},
{
prop: 'hobbies',
label: '爱好'
},
{
prop: 'education',
label: '学历'
},
{
prop: 'occupation',
label: '职业'
},
{
prop: 'address',
label: '联系地址'
}
]
}
},
methods: {
added() {
console.log('点击了新增高质量人类')
}
}
}
</script>
这里的
floatButton
并非真的有这个属性,而是代指floatButtonSet
的每个子元素、表示的是每一个浮动按钮
的具体配置信息,这里的每个子元素之间的顺序在页面上展示的顺序对应。
目前表格列的类型分为三种: 普通按钮
、下拉菜单按钮
、自定义按钮
。
- 类型:
String
- 必传:
是
- 可选值:
button (普通按钮)
、dropdown(下拉菜单按钮)
、slot(插槽、自定义列)
。
<template>
<table-page title="高质量人类" :tableData="tableData"></table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: [],
provide() {
return {
floatButtonSet: [
{
renderType: 'button'
},
{
renderType: 'slot'
},
{
renderType: 'dropdown'
}
]
}
}
}
}
}
</script>
只作用于 button (普通按钮)
和 dropdown (下拉菜单按钮)
- 类型:
String
- 必传:
否
<template>
<table-page title="高质量人类" :tableData="tableData"></table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: [],
provide() {
return {
floatButtonSet: [
{
renderType: 'button',
text: '新增高质量人类'
},
{
renderType: 'slot'
},
{
renderType: 'dropdown',
text: '导出数据'
}
]
}
}
}
}
}
</script>
按钮的颜色风格, 沿用 Element ui
按钮风格, 只作用于 button (普通按钮)
和 dropdown (下拉菜单按钮)
。
- 类型:
String
- 必传:
否
- 可选值:
primary
,success
,info
,warning
,danger
, 不传参数则为黑白按钮。
<template>
<table-page title="高质量人类" :tableData="tableData"></table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: [],
provide() {
return {
floatButtonSet: [
{
renderType: 'button',
text: '新增高质量人类',
type: 'primary'
},
{
renderType: 'slot'
},
{
renderType: 'dropdown',
text: '导出数据',
type: 'info'
}
]
}
}
}
}
}
</script>
接收一个函数,在按钮点击时执行,作用于 button (普通按钮)
。
- 类型:
Function
- 必传:
是
<template>
<table-page title="高质量人类" :tableData="tableData"></table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: [],
provide() {
return {
floatButtonSet: [
{
renderType: 'button',
text: '新增高质量人类',
type: 'primary',
onClick: this.added
},
{
renderType: 'slot'
},
{
renderType: 'dropdown',
text: '导出数据',
type: 'info'
}
]
}
}
}
},
methods: {
added() {
console.log('新增高质量人类名单')
}
}
}
</script>
字体图标名称, Element UI
图标, 只作用于 button (普通按钮)
。
- 类型:
String
- 必传:
否
<template>
<table-page title="高质量人类" :tableData="tableData"></table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: [],
provide() {
return {
floatButtonSet: [
{
renderType: 'button',
text: '新增高质量人类',
type: 'primary',
onClick: this.added,
icon: 'el-icon-edit'
},
{
renderType: 'slot'
},
{
renderType: 'dropdown',
text: '导出数据',
type: 'info'
}
]
}
}
}
},
methods: {
added() {
console.log('新增高质量人类名单')
}
}
}
</script>
接收一个 对象数组
, 数组内每一个 对象
表示一个 下拉菜单项
,只作用于 dropdown (下拉菜单按钮)
。
- 类型:
Array
- 必传:
类型为 dropdown 时必传
<template>
<table-page title="高质量人类" :tableData="tableData"></table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: [],
provide() {
return {
floatButtonSet: [
{
renderType: 'button',
text: '新增高质量人类',
type: 'primary',
onClick: this.added
},
{
renderType: 'slot'
},
{
renderType: 'dropdown',
text: '导出数据',
type: 'info',
menuSet: [
{}
]
}
]
}
}
}
},
methods: {
added() {
console.log('新增高质量人类名单')
}
}
}
</script>
这里的 menu
并非真的有这个属性,而是代指 menuSet
的每个子元素,表示的是每一个 下拉菜单项
。
- 类型:
String
- 必传:
否
<template>
<table-page title="高质量人类" :tableData="tableData"></table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: [],
provide() {
return {
floatButtonSet: [
{
renderType: 'button',
text: '新增高质量人类',
type: 'primary',
onClick: this.added
},
{
renderType: 'slot'
},
{
renderType: 'dropdown',
text: '导出数据',
type: 'info',
menuSet: [
{
text: '导出高质量男孩'
}
]
}
]
}
}
}
},
methods: {
added() {
console.log('新增高质量人类名单')
}
}
}
</script>
接收一个函数,在下拉菜单项按钮点击时执行。
- 类型:
Function
- 必传:
是
<template>
<table-page title="高质量人类" :tableData="tableData"></table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: [],
provide() {
return {
floatButtonSet: [
{
renderType: 'button',
text: '新增高质量人类',
type: 'primary',
onClick: this.added
},
{
renderType: 'slot'
},
{
renderType: 'dropdown',
text: '导出数据',
type: 'info',
menuSet: [
{
text: '导出高质量男孩',
onClick: this.leadingOutBoys
},
{
text: '导出高质量女孩',
onClick: this.leadingOutGirls
}
]
}
]
}
}
}
},
methods: {
added() {
console.log('新增高质量人类名单')
},
leadingOutBoys() {
console.log('导出高质量男孩名单')
},
leadingOutGirls() {
console.log('导出高质量女孩名单')
}
}
}
</script>
只作用于 button (普通按钮)
和 dropdown (下拉菜单按钮)
。
- 类型:
Boolean
- 必传:
否
<template>
<table-page title="高质量人类" :tableData="tableData"></table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: [],
provide() {
return {
floatButtonSet: [
{
renderType: 'button',
text: '新增高质量人类',
type: 'primary',
onClick: this.added,
disabled: true
},
{
renderType: 'slot'
},
{
renderType: 'dropdown',
text: '导出数据',
type: 'info',
menuSet: [
{
text: '导出高质量男孩',
onClick: this.leadingOutBoys
},
{
text: '导出高质量女孩',
onClick: this.leadingOutGirls
}
],
disabled: false
}
]
}
}
}
},
methods: {
added() {
console.log('新增高质量人类名单')
},
leadingOutBoys() {
console.log('导出高质量男孩名单')
},
leadingOutGirls() {
console.log('导出高质量女孩名单')
}
}
}
</script>
用于配合项目中的自定义指令 v-permission
,若项目中没有该指令,则无效。
- 类型:
Array
||String
- 必传:
否
在某些时候,我们预设的按钮不满足需求,就需要使用到插槽来实现自定义按钮,在接收 slot
字段之前,务必先将 renderType
的值设置为 slot
- 类型:
String
- 必传:
否
<template>
<table-page title="高质量人类" :tableData="tableData">
<template slot="more">
<el-dropdown split-button type="primary" size="small">
更多名单
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>凶猛的小萝莉</el-dropdown-item>
<el-dropdown-item>沧伤的小正太</el-dropdown-item>
<el-dropdown-item>娇萌的怪叔叔</el-dropdown-item>
<el-dropdown-item>恐怖的御姐姐</el-dropdown-item>
<el-dropdown-item>性感的老阿姨</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
</table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: [],
provide() {
return {
floatButtonSet: [
{
renderType: 'slot',
slot: 'more'
}
]
}
}
}
}
}
</script>
搜索栏提供各种
类型
控件的搜索项,包括普通文本框
、下拉菜单
等等,点击查询按钮
将会暴露出查询事件
,具体代码需要自行编写,点击重置则清空搜索栏,它将出现在表格上方, 它是一个容器,由一个或者多个搜索项
组成, 如果内置的搜索控件
不满足需求,可利用插槽自定义搜索项
。
- 传入方式:
Provide
- 类型:
Array
,对象数组
,每个元素都应该是一个对象,而每个对象表示每个搜索项
的配置信息 - 必传:
否
在点击
查询
、重置
按钮时, 会暴露出对应的事件
- 传入方式
prop
- 类型:
Function
- 必传:
是
- 回调参数:
search
包含内置搜索项
绑定的值
<template>
<table-page title="高质量人类" :tableData="tableData" @onSearch="onSearch"></table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: []
}
},
methods: {
onSearch(search) {
console.log(search)
}
}
}
</script>
- 传入方式
prop
- 类型:
Function
- 必传:
否
<template>
<table-page title="高质量人类" :tableData="tableData" @onSearch="onSearch" @onClear="onClear"></table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: []
}
},
methods: {
onSearch(search) {
console.log(search)
},
onClear() {
// 这里可以重置一些自定义搜索项的值
}
}
}
</script>
这里的
searchItem
并非真的有这个属性,而是代指searchBarSet
的每个子元素、表示的是每一个搜索项
的具体配置信息,这里的每个子元素之间的顺序在页面上展示的顺序对应。
目前搜索项内置的控件类型分为三种: input (输入框)
、select (选择器)
、slot (自定义搜索项)
。
- 类型:
String
- 必传:
是
- 可选值:
input (输入框)
、select (选择器)
、slot (自定义搜索项)
。
<template>
<table-page title="高质量人类" :tableData="tableData" @onSearch="onSearch"></table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: [],
provide() {
return {
searchBarSet: [
{
renderType: 'input'
},
{
renderType: 'select'
},
{
renderType: 'slot'
}
]
}
}
}
},
methods: {
onSearch(search) {
console.log(search)
}
}
}
</script>
出现在每个 搜索项
控件左侧的文本信息
- 类型:
String
- 必传:
否
<template>
<table-page title="高质量人类" :tableData="tableData" @onSearch="onSearch"></table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: [],
provide() {
return {
searchBarSet: [
{
renderType: 'input',
label: '姓名'
},
{
renderType: 'select',
label: '学历'
},
{
renderType: 'slot',
label: '出生日期'
}
]
}
}
}
},
methods: {
onSearch(search) {
console.log(search)
}
}
}
</script>
只作用于 input (输入框)
、select (选择器)
- 类型:
String
- 必传:
是
<template>
<table-page title="高质量人类" :tableData="tableData" @onSearch="onSearch"></table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: [],
provide() {
return {
searchBarSet: [
{
renderType: 'input',
label: '姓名',
key: 'name'
},
{
renderType: 'select',
label: '学历',
key: 'education'
},
{
renderType: 'slot',
label: '出生日期'
}
]
}
}
}
},
methods: {
onSearch(search) {
console.log(search)
}
}
}
</script>
只作用于 input (输入框)
、select (选择器)
- 类型:
String
- 必传:
否
<template>
<table-page title="高质量人类" :tableData="tableData" @onSearch="onSearch"></table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: [],
provide() {
return {
searchBarSet: [
{
renderType: 'input',
label: '姓名',
key: 'name',
placeholder: '请输入姓名'
},
{
renderType: 'select',
label: '学历',
key: 'education',
placeholder: '请选择学历'
},
{
renderType: 'slot',
label: '出生日期'
}
]
}
}
}
},
methods: {
onSearch(search) {
console.log(search)
}
}
}
</script>
只作用于 input (输入框)
、select (选择器)
- 类型:
Number
- 必传:
否
<template>
<table-page title="高质量人类" :tableData="tableData" @onSearch="onSearch"></table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: [],
provide() {
return {
searchBarSet: [
{
renderType: 'input',
label: '姓名',
key: 'name',
placeholder: '请输入姓名',
width: 240
},
{
renderType: 'select',
label: '学历',
key: 'education',
placeholder: '请选择学历',
width: 240
},
{
renderType: 'slot',
label: '出生日期'
}
]
}
}
}
},
methods: {
onSearch(search) {
console.log(search)
}
}
}
</script>
只作用于 select (选择器)
- 类型:
Array
,对象数组
,数组内的每个对象表示一个选项
,该对象接收两个参数:value
,label
, 分别表示当前选项的值和名称 - 必传: 类型为
select (选择器)
时,必传
<template>
<table-page title="高质量人类" :tableData="tableData" @onSearch="onSearch"></table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: [],
provide() {
return {
searchBarSet: [
{
renderType: 'input',
label: '姓名',
key: 'name',
placeholder: '请输入姓名',
width: 240
},
{
renderType: 'select',
label: '学历',
key: 'education',
placeholder: '请选择学历',
width: 240,
options: [
{
value: '专科',
label: '专科'
}, {
value: '本科',
label: '本科'
}, {
value: '硕士',
label: '硕士'
}, {
value: '博士',
label: '博士'
}
]
},
{
renderType: 'slot',
label: '出生日期'
}
]
}
}
}
},
methods: {
onSearch(search) {
console.log(search)
}
}
}
</script>
在某些时候,我们预设的 搜索项
不满足需求,就需要使用到插槽来实现 自定义搜索项
,在接收 slot
字段之前,务必先将 renderType
的值设置为 slot
- 类型:
String
- 必传:
否
<template>
<table-page title="高质量人类" :tableData="tableData" @onSearch="onSearch">
<template slot="birthday" slot-scope="scope">
<el-date-picker size="small" v-model="birthday" type="date" placeholder="选择日期"></el-date-picker>
</template>
</table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: [],
provide() {
return {
searchBarSet: [
{
renderType: 'slot',
slot: 'birthday',
label: '出生日期'
}
]
}
}
}
},
methods: {
onSearch(search) {
console.log(search)
}
}
}
</script>
提供表格底部分页,由于分页需要跟表格交互而
provide
和inject
的绑定并不是可响应的,所以它的传入方式稍微有点不一样,依然是以Provide
的方式传入,但是接收的是一个具有返回绑定分页配置信息对象的函数。
- 传入方式:
Provide
- 类型:
Function
- 必传:
否
-
在
data
创建一个对象类型的变量pagination
,用于操作分页信息,变量名可以自取,这里以pagination
为例 -
在
Provide
创建一个paginationSet
用于将data
中创建的对象传入到组件 -
在请求接口的方法中,改变
pagination
的值,使组件产生交互
<template>
<table-page title="高质量人类" :tableData="tableData" :loading="loading"></table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
pagination: {},
tableData: [],
loading: false
}
},
provide() {
return {
paginationSet: () => this.pagination
}
},
methods: {
getData(page = 1, pageSize = 10, search = {}) {
this.loading = true
// 模拟接口
axios.get('https://mock.ogliu.com/mock/618484ed957ff105d1b54bad/api/list', {
params: { page, pageSize, ...search }
}).then(response => {
this.tableData = response.data.data
this.pagination = {
size: pageSize,
total: response.data.meta.pagination.total,
current: response.data.meta.pagination.current_page
}
this.loading = false
}).catch(function (error) {
console.log(error)
})
}
}
}
</script>
paginationSet
对使组件对外产生分页相关的事件,对应Element UI
分页事件
- 传入方式:
Prop
- 类型:
Function
- 必传:
否
- 回调参数:
当前页
<template>
<table-page
title="高质量人类"
:tableData="tableData"
:loading="loading"
@currentChange="currentChange">
</table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
pagination: {},
tableData: [],
loading: false
}
},
provide() {
return {
paginationSet: () => this.pagination
}
},
methods: {
currentChange(page) {
console.log(page)
}
}
}
</script>
- 传入方式:
Prop
- 类型:
Function
- 必传:
否
- 回调参数:
每页条数
<template>
<table-page
title="高质量人类"
:tableData="tableData"
:loading="loading"
@sizeChange="sizeChange">
</table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
pagination: {},
tableData: [],
loading: false
}
},
provide() {
return {
paginationSet: () => this.pagination
}
},
methods: {
sizeChange(size) {
console.log(size)
}
}
}
</script>
这里指的是
data
中存储的pagination
对象, 由于操作方式都一样,这里就不一一给出demo
演示了,展示一个完整版demo
,请自行查阅对应选项。
<template>
<table-page
title="高质量人类"
:tableData="tableData"
:loading="loading"
@currentChange="currentChange"
@sizeChange="sizeChange">
</table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
pagination: {
current: 1,
total: 0,
size: 10,
sizes: [10, 20, 30, 40, 50, 100],
layout: 'total, sizes, prev, pager, next, jumper'
},
tableData: [],
loading: false
}
},
provide() {
return {
paginationSet: () => this.pagination
}
},
methods: {
getData(page = 1, pageSize = 10, search = {}) {
this.loading = true
// 模拟接口
axios.get('https://mock.ogliu.com/mock/618484ed957ff105d1b54bad/api/list', {
params: { page, pageSize, ...search }
}).then(response => {
this.tableData = response.data.data
this.pagination = {
size: pageSize,
total: response.data.meta.pagination.total,
current: response.data.meta.pagination.current_page
}
this.loading = false
}).catch(function (error) {
console.log(error)
})
},
sizeChange(size) {
console.log(size)
},
currentChange(page) {
console.log(page)
}
}
}
</script>
- 传入方式:
pagination
属性 - 类型:
Number
, - 必传:
否
- 传入方式:
pagination
属性 - 类型:
Number
, - 必传:
否
- 传入方式:
pagination
属性 - 类型:
Number
- 必传:
否
- 默认值:
10
- 传入方式:
pagination
属性 - 类型:
NumberArray
, 数字数组 - 必传:
否
- 默认值: [10, 20, 30, 40, 50, 100]
- 传入方式:
pagination
属性 - 类型:
String
- 必传:
否
- 可选参数:
sizes
,prev
,pager
,next
,jumper
,total
- 默认值:
sizes
,prev
,pager
,next
,jumper
,total
需要注意与
row-key
配合使用,row-key
默认值是id
,若数据唯一标识需要自定义则需要自行传入对应字段。
- 传入方式:
Provide
- 类型:
Array
,对象数组
,每个元素都应该是一个对象,而每个对象表示每个批量的操作项
- 必传:
否
<template>
<table-page title="高质量人类" :tableData="tableData" row-key="name"></table-page>
</template>
<script type="text/ecmascript-6">
export default {
provide() {
return {
batchHandleSet: [
{
content: '开始',
svg: {
name: 'start'
},
event: 'doStart'
},
{
content: '停止',
svg: {
width: '16',
height: '16',
name: 'off'
},
event: 'doStop'
}
]
}
},
data() {
return {
tableData: [],
loading: false
}
}
}
</script>
表格数据加载动画
- 类型:
Boolean
- 必传:
否
<template>
<table-page title="高质量人类" :tableData="tableData" :loading="loading"></table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: [],
loading: false
}
}
}
</script>
表格底部返回上一页按钮,它会暴露一个回调事件 goBack
,需结合使用。
- 类型:
Boolean
- 必传:
否
<template>
<table-page
title="高质量人类"
:tableData="tableData"
:loading="loading"
backButton
@goBack="goBack">
</table-page>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
tableData: [],
loading: false
}
},
methods: {
goBack() {
console.log('点击了返回按钮')
}
}
}
</script>
-
由于组件整体体积过于庞大(2.05M), 重新组织组件源码,超大幅度减小体积,优化过后打包体积降至 21KB。
-
固定显示横向滚动条
功能所需依赖多且杂,项目中也无实际应用,所以移除该功能。 -
移除
vuejs-sticky-directive
插件在组件源码内部的引入及使用,这将意味着调用方需要提供该插件。 -
配置
source-map
,提升性能。
浮动按钮
、操作按钮
新增permission
选项配置,用于配合v-permission
自定义指令。- 解决文档菜单栏上方图片无法加载的问题。
- 屏蔽文档
在线预览
报错信息 - 限制文档
在线预览
最低宽度,保证它不会因为宽度不够而错位 - 解决文档
在线预览
搜索条中的下拉菜单按钮左右高度不一致问题。 - 解决文档
在线预览
部分报错问题。
- 解决
el-tabble
搭配v-loadding
导致表格上、右外边框渲染问题
- 新增 批量操作 功能
- 新增 固定显示横向滚动条 功能
- 搜索栏新增(自定义搜索项)插槽
- 浮动按钮新增(自定义按钮项)插槽
- 浮动按钮新增
disabled
禁用属性 - 搜索栏重置按钮新增事件
@onClear
- 命名规范化
- 防止与
ElementUI
属性冲突,原本控件类型type
更改为renderType
- 集合统一添加
Set
后缀 - 加强语义化,下拉菜单按钮
list
更改为menuSet
- 防止与
- 为了化繁为简,更好的分类处理,将原本
分页子组件
完全重写,使用Provide
传入参数 - 新增副标题
subtitle
持续开发、更新、优化,暂时计划要实现的功能如下:
-
搜索栏新增高级搜索
-
表格新增筛选列功能
-
浮动按钮新增svg图标
-
搜索栏新增更多控件类型的搜索项
-
浮动按钮新增更多控件类型的按钮项