@mecc/table
v1.1.1
Published
Advanced vue table component based on el-table.
Downloads
8
Maintainers
Readme
@mecc/table
Intro 简介
@mecc/table
是一款表格组件,基于 vue
和 element-ui
进行的二次封装,无需繁琐的模板代码,所有的表格列配置项均可通过属性传递,使你的代码更干净。
Feature 特色
@mecc/table
通过column
属性来实现表格列的配置,灵活的JSX
语法便于高度自定义表格组件;@mecc/table
采用$attrs
和$listeners
接收参数和监听事件,无缝对接element-ui
中的Table
文档板块,包含自定义slot
插槽,上手更快;column
每列配置,最低限度仅传递prop
和label
属性,就可实现标准值输出,也可以使用formatter
或render
属性进行格式化输出;
Install 安装
- 通过
npm
或者yarn
安装项目
npm i @mecc/table
# 或者
yarn add @mecc/table
- 引用组件,根据需要可全局引入或者局部引入
// 组件依赖 vue 和 element-ui
// 全局引入
// >>> main.js
import Vue from 'vue'
import Element from 'element-ui'
import 'element-ui/libs/theme-chalk/index.css'
import MeccTable from '@mecc/table'
Vue.use(MeccTable, options) // @mecc/table 全局引用时可传入配置项,具体内容见下方
// 局部引入
// >>> Demo.vue
<script>
import MeccTable from '@mecc/table'
export default {
components: {
MeccTable
}
}
</script>
Options 配置项
配置项内容可在全局引入时设置,或者直接使用 <mecc-table {...options} />
,需注意:直接使用的优先级高于全局配置
| 参数 | 数据类型 | 默认值 | 可选值 | 说明 | |:----------------------:|:--------:|:------:|:-----------------:|:----------------------------------:| | colAlign | String | center | left/right/center | 设置表格列的对齐方式 | | colHeaderAlign | String | center | left/right/center | 设置表头的对其方式 | | colEmptyText | String | '-' | - | 表格单元数据为空时显示的文本内容 | | pagerOffset | Number | 0 | - | 设置分页器与表格的间距,单位是'px' | | customClassName | String | '' | - | 自定义class名称 | | tablePadding | Number | 0 | - | Table的Padding值,计算表格高度会用 | | colShowOverflowTooltip | Boolean | false | true/false | 当内容过长被隐藏时显示 tooltip |
Table Attributes 表格属性
仅展示必填项和新增项,其余参数见 Element Doc Table #Table-column Attributes 及 Element Doc Pagination
| 参数 | 数据类型 | 是否必须 | 默认值 | 可选值 | 说明 | |:----------------------:|:--------:|:--------:|:------:|:-----------------:|:----------------------------------:| | data | Array | 是 | - | - | 表格数据 | | column | Array | 是 | - | - | 表格列配置项,具体内容见下方说明 | | pagination | Boolean | 否 | false | - | 是否显示分页器 | | pagerOffset | Number | 否 | 0 | - | 设置分页器与表格的间距,单位是'px' | | colAlign | String | 否 | center | left/right/center | 设置表格列的对齐方式 | | colHeaderAlign | String | 否 | center | left/right/center | 设置表头的对其方式 | | colEmptyText | String | 否 | '-' | - | 表格单元数据为空时显示的文本内容 | | customClassName | String | 否 | - | - | 自定义class名称 | | tablePadding | Number | 否 | 0 | - | Table的Padding值,计算表格高度会用 | | colShowOverflowTooltip | Boolean | 否 | false | true/false | 当内容过长被隐藏时显示 tooltip |
Table Events 表格事件
仅展示新增事件,其余事件见 Element Doc Table #Table Events 及 Element Doc Pagination
| 事件名 | 说明 | 参数 | |:--------------------:|:----------------------------------:|:-------------------------:| | page-change | 同 el-pagination 的 current-change | currentPage | | table-current-change | 同 el-table 的 current-change | currentRow, oldCurrentRow |
Table Methods 表格方法
支持全部 el-table
和 el-pagination
方法,详见 Element Doc Table #Table Methods 及 Element Doc Pagination
Table Slot 表格插槽
| name | 说明 | |:----------:|:------------------------------------------------------------------------:| | append | 插入至表格最后一行之后的内容。若表格有合计行,该 slot 会位于合计行之上。 | | empty | 空数据时显示的文本内容。 | | pagination | 分页器中的自定义内容,需要在 layout 中列出 slot |
Column 列配置项
仅展示必填项和新增项,其余参数见 Element Doc Table #Table-column Attributes
| 参数 | 数据类型 | 是否必须 | 说明 | |:---------:|:-----------------------------------:|:--------:|:------------------------------:| | prop | String | 是 | 设置表格列的对齐方式 | | label | String | 是 | 设置表头的对其方式 | | render | Function(h, context)/VNode | 否 | 自定义渲染内容,可选返回VNode | | formatter | Function(row, column, index)/String | 否 | 自定义渲染内容,可选返回字符串 | | show | Function()/Boolean | 否 | 是否渲染该列,默认渲染 |
Usage Example 使用示例
- 所有
<el-table>
接受的属性和事件,<mecc-table>
都接受 - 由于
<el-table>
和<el-pagination>
同时存在事件 @current-change , 建议使用 @table-current-change 和 @page-change 区分 <mecc-table>
接受一些新属性,见配置清单<mecc-table>
中实现了<el-table>
和<el-pagination>
的所有<slot>
- 需要注意:
<el-pagination>
的自定义插槽在<mecc-table>
中为<slot name="pagination">
<template>
<mecc-table
:data="dataList"
:column="column"
stripe
layout="slot, -> , prev, pager, next, jumper, sizes, total"
:pagination="total / pageSize > 1"
:total="total"
:current-page.sync="currentPage"
:page-size="pageSize"
highlight-current-row
hide-on-single-page
col-align="center"
col-header-align="left"
@page-change="handlePageChange"
@size-change="handleSizeChange"
@table-current-change="handleCurrentChange"
>
<template #pagination>
<span>Guess Page Game</span>
</template>
<template #empty>
<span>Guess Page Game</span>
</template>
</mecc-table>
</template>
<script>
export default {
data() {
return {
currentPage: 1,
pageSize: 10,
customHeader: 'MeccTable',
cache: {}
};
},
computed: {
dataList() {
const res = [];
for (let idx = 0; idx < 30; idx++) {
res.push({
name: 'mecc' + idx,
// age: idx,
gender: idx % 2 ? 'male' : 'female',
hobby: ['html', 'css', 'js'],
isEdit: false
});
}
return res;
},
total() {
return this.dataList.length;
},
column() {
return [
{
prop: 'name',
label: '姓名'
},
{
prop: 'custom_hidden',
label: '自定义隐藏',
show: () => false
},
{
prop: 'age',
label: '年龄',
formatter: (row, column, index) => {
if (row[column.property]) {
return row[column.property] + '岁';
}
},
renderHeader: (h, ctx) => {
return <el-input v-model={this.customHeader} size='mini' />;
}
},
{
prop: 'gender',
label: '性别',
render: (h, ctx) => {
const genderNameMap = { male: '男生', female: '女生' };
if (ctx.row.gender) {
return (
<el-tag
type={ctx.row.gender === 'male' ? 'danger' : 'success'}
size='mini'
>
{genderNameMap[ctx.row.gender]}
</el-tag>
);
}
}
},
{
prop: 'hobby',
label: '兴趣',
render: (h, ctx) => {
if (!ctx.row.hobby || !ctx.row.hobby.length) return;
if (!ctx.row.isEdit) {
const hobbyList = ctx.row.hobby.map(item => (
<el-tag size='mini' style='margin-right: 5px;'>
{item}
</el-tag>
));
return <div>{hobbyList}</div>;
}
const options = [
{
name: '前端',
id: 'front',
children: [
{
name: 'HTML',
id: 'html'
},
{
name: 'JavaScript',
id: 'js'
},
{
name: 'CSS',
id: 'css'
}
]
},
{
name: '后端',
id: 'back',
children: [
{
name: 'JAVA',
id: 'java'
},
{
name: 'Golang',
id: 'golang'
},
{
name: 'Python',
id: 'python'
}
]
}
];
/**
* 特别注意
* 由于 el-cascader 需要传递名称为 'props' 的属性
* 而在 vue 的 JSX 语法解析中,'props' 属性无法正常传递,所以这里需要特殊处理下
* 详情可参考 https://www.yuque.com/zeka/vue/vu60wg
*/
const cascaderProps = {
options,
props: {
checkStrictly: true,
label: 'name',
value: 'id',
multiple: true,
emitPath: false
},
clearable: true,
filterable: true
};
return (
<el-cascader
{...{ props: cascaderProps }}
v-model={ctx.row.hobby}
/>
);
}
},
{
prop: 'operate',
label: '操作',
align: 'center',
headerAlign: 'center',
render: (h, ctx) => {
const handleEdit = () => {
this.cache[ctx.row.name] = JSON.parse(JSON.stringify(ctx.row));
ctx.row.isEdit = true;
};
const handleCancel = () => {
Object.assign(ctx.row, this.cache[ctx.row.name]);
ctx.row.isEdit = false;
};
const handleConfirm = () => {
setTimeout(() => {
console.log('修改成功');
ctx.row.isEdit = false;
});
};
if (!ctx.row.isEdit) {
return (
<el-button type='primary' size='mini' onClick={handleEdit}>
编辑
</el-button>
);
}
return (
<el-button-group>
<el-button type='success' size='mini' onClick={handleConfirm}>
保存
</el-button>
<el-button type='info' size='mini' onClick={handleCancel}>
取消
</el-button>
</el-button-group>
);
}
}
];
}
},
methods: {
handleCurrentChange(val, old) {
console.log('row', val, old);
},
handlePageChange(val) {
console.log('page: ', val);
},
handleSizeChange(val) {
console.log('size: ', val);
this.pageSize = val;
this.currentPage = 1;
}
}
};
</script>