自己封装的element-ui的table插件,实现render渲染,插槽等功能
element
A Vue.js 2.0 UI Toolkit for Web
项目地址:https://gitcode.com/gh_mirrors/eleme/element
免费下载资源
·
前言:
再通过使用element-ui和iview这两种框架的table时的对比发现,iview比ele有个优点就是,他中间支持render渲染,但是iview的事件又是明显少于ele的,比如我们需要右键的事件,或者点击表头的事件,在iview是得不到解决的,所以在这里我对element的table进一步封装,使得他可以更好的满足我们的需要:
首先我在这里是需要引入两个组件的:(先代码,再谈谈怎么实现的)
第一个组件:iTableT.vue,这里面主要是对得到的数据进行处理,并实现功能的底层功能组件
<!--region 封装的分页 table-->
<template>
<div class="table">
<el-table id="iTable" :class="tableClass"
v-loading.iTable="options.loading"
:data="list"
:stripe="options.stripe"
:border="options.border"
:highlight-current-row="options.highlightCurrentRow"
:lazy="options.lazy"
:load='loadGetData'
ref="mutipleTable"
style='width:100%;'
@row-click='clickRow' @row-dblclick='dblclickRow' @row-contextmenu='contextmenu' @header-click='headClick' @header-contextmenu='headcontextmenu'
@current-change='rowChange'
@selection-change="handleSelectionChange">
<!--region 选择框-->
<el-table-column v-if="options.mutiSelect" type="selection" style="width: 55px;">
</el-table-column>
<!--endregion-->
<!--region 数据列-->
<template v-for="(column, index) in columns">
<!-- slot 添加自定义配置项 -->
<slot v-if="column.slot" :name="column.slot"></slot>
<!--排序-->
<el-table-column v-else-if="column.type=='index'" type="index" :width="column.width" :label="column.label"></el-table-column>
<!-- 默认渲染列 -->
<el-table-column v-else :prop="column.prop"
:key='column.label'
:label="column.label"
:align="column.align"
:width="column.width"
:show-overflow-tooltip="true">
<template slot-scope="scope">
<template v-if="!column.render">
<template v-if="column.formatter">
<span v-html="column.formatter(scope.row, column)"></span>
</template>
<template v-else>
<span>{{scope.row[column.prop]}}</span>
</template>
</template>
<template v-else>
<expand-dom :column="column" :row="scope.row" :render="column.render" :index="index"></expand-dom>
</template>
</template>
</el-table-column>
</template>
<!--endregion-->
</el-table>
</div>
</template>
<!--endregion-->
<script>
export default {
props: {
list: {
type: Array,
default: []
}, // 数据列表
columns: {
type: Array,
default: []
}, // 需要展示的列 === prop:列数据对应的属性,label:列名,align:对齐方式,width:列宽
options: {
type: Object,
default: {
height:300,//默认高度-为了表头固定
stripe: false, // 是否为斑马纹 table
highlightCurrentRow: false, // 是否要高亮当前行
border:false,//是否有纵向边框
lazy:false,//是否需要懒加载
},
}, // table 表格的控制参数
tableClass:{
type: String,
default: 'hxTable'
},
},
//组件
components: {
expandDom: {
functional: true,
props: {
row: Object,
render: Function,
index: Number,
column: {
type: Object,
default: null
}
},
render: (h, ctx) => {
const params = {
row: ctx.props.row,
index: ctx.props.index
}
if (ctx.props.column) params.column = ctx.props.column
return ctx.props.render(h, params)
}
}
},
// 数据
data () {
return {
pageIndex: 1,
multipleSelection: [], // 多行选中
}
},
mounted () {
},
computed: {
},
methods: {
loadGetData(row,treeNode,resolve){//懒加载事件数据
},
handleSelectionChange (val) {// 多行选中
this.multipleSelection = val
this.$emit('handleSelectionChange', val)
},
clickRow(row, column, event){//单击行事件
let data = {
'row':row,
'column':column,
'event':event,
}
this.$emit('clickRow',data);
},
dblclickRow(row, column, event){//双击行事件
let data = {
'row':row,
'column':column,
'event':event,
}
this.$emit('dblclickRow',data);
},
contextmenu(row, column, event){//右键行事件-没去掉页面默认的
let data = {
'row':row,
'column':column,
'event':event,
}
this.$emit('contextmenu',data);
},
headClick(column, event){//头部列点击事件
let data = {
'column':column,
'event':event,
}
this.$emit('headClick',data);
},
headcontextmenu(column, event){//头部列右键点击事件
let data = {
'column':column,
'event':event,
}
this.$emit('headcontextmenu',data);
},
rowChange(currentRow, oldCurrentRow){//当前行发生改变时的事件
let data = {
'currentRow':currentRow,
'oldCurrentRow':oldCurrentRow,
}
this.$emit('rowChange',data);
},
}
}
</script>
<style lang="less" >
</style>
第二:第二个组件是我的slot组件,这里是专门提出来了,来实现我们更多的需要:
<template>
<div class="tableSlot" style="">
<CommonTable
:columns="columns" :list="list" :options='optionsData'
@clickRow='clickRow' @dblclickRow='dblclickRow' @contextmenu='contextmenu' @headClick='headClick' @headcontextmenu='headcontextmenu'
@rowChange='rowChange' @handleSelectionChange='handleSelectionChange'
>
<!-- 内容slot -->
<el-table-column slot="operate" label="操作">
<template slot-scope="scope">
<el-button type="text" size="small" @click="edit(scope.row)">编辑</el-button>
<el-button type="text" size="small" @click="deleteUser(scope.row)">删除</el-button>
</template>
</el-table-column>
<el-table-column slot="twomenu" label="二级图层">
<template slot-scope="scope">
<span class="demonstration">{{ scope.row.twomenu }}</span>
<el-cascader
v-model="value"
:options="options"
:props="{ expandTrigger: 'hover' }"
@change="handleChange"
:show-all-levels="false">
</el-cascader>
</template>
</el-table-column>
<!--排序-->
<el-table-column slot="index" label="排序">
<template slot-scope="scope">
<span>{{(paging.pageNum - 1) * paging.pageSize + scope.$index + 1}}</span>
</template>
</el-table-column>
<!-- 头部slot -->
<el-table-column width=150 prop="zt" slot="name">
<template slot-scope="scope" slot="header">
<el-popover
title="标题"
width="200"
trigger="click"
content="这是一段内容,这是一段内容,这是一段内容,这是一段内容。">
<span slot="reference">姓名</span>
</el-popover>
</template>
</el-table-column>
</CommonTable>
</div>
</template>
<script>
import CommonTable from '@/components/tableEle/iTableT'//table
// import CommonTable from '@/components/tableEle/iTable'//table
export default {
name:'slot统一管理',
props:{
columns:Array,
list:Array,
options:Object,
//将当前页和一页显示多少条作为参数传进来保证序号的准确性
paging: {
type:Object,
default: () => {
return {
pageNum: 1,
pageSize: 10,
}
}
}
},
data () {
return {
optionsData:{
stripe: false, // 是否为斑马纹 table
loading: false, // 是否添加表格loading加载动画
highlightCurrentRow: true, // 是否支持当前行高亮显示
mutiSelect: false, // 多选框
height:400,//table高度-设置才能固定表头
}, // table 的参数
};
},
components: {
CommonTable
},
created(){
document.oncontextmenu = function(){return false};//去掉右键点击默认菜单
if( this.options != undefined){
this.optionsData = this.options;
}
},
methods: {
handleSelectionChange(data){//选择项发生改变,勾选框
this.$emit('handleSelectionChange', data)
},
clickRow(data){//点击行事件
this.$emit('clickRow', data)
},
dblclickRow(data){//双击行事件
this.$emit('dblclickRow', data)
},
contextmenu(data){//右键点击事件
this.$emit('contextmenu', data)
},
headClick(data){//头部列点击事件
this.$emit('headClick', data)
},
headcontextmenu(data){//头部列右键点击事件
this.$emit('headcontextmenu', data)
},
rowChange(data){//当前行发生改变
this.$emit('rowChange', data)
},
},
}
</script>
<style lang='less' scoped>
</style>
第三是调动部分的代码:
<cTable
:columns="GJcolumns"
:list="TqycgjxxData"
tableClass="jrzytjTb"
:paging="searchForm" 加上这个以后就可用slot:'index',方法源码在cTable.vue里面
></cTable>
//注意这里封装了一个class,可以设置每个table的class,目的用来更改他的高度,实现头部固定,上下滚动条的效果
data里面的数据:
//查询参数
searchForm:{
name:'',
type:'',
pageNum:1,//当前页
pageSize:10,//一页显示多少条
},
GJcolumns:{
{
label:'序号',
slot:'index', //使用这个的话,必须传入paging这个参数(自用)
//type:'index', 如果使用这个是element默认的序号
width:55
},
{
label: 'id',
prop: 'id',
align: 'center',
width: 1,
},
{
label: '线路',
prop: 'ssxl',
align: 'center',
width: 126,
},
{
label: '台区',
prop: 'tqmc',
align: 'center',
width: 126,
},
{
slot:'select',//注意这里是引用slot
align: 'center',
width: 126,
},
{
label: '异常描述',
prop: 'ycms',
align: 'center',
width: 126,
},
{
label: '发生时间',
prop: 'fssj',
align: 'center',
width: 170,
},
{
label: '等级',
prop: 'qxdj',
align: 'center',
width: 110,
render: (h, params) => {
let dj = params.row.qxdj;
let style={};
if(dj == '一般'){
style.color = '#00fffc';
}else if(dj == '重大'){
style.color = '#ff5816';
}else if(dj == '紧急'){
style.color = '#ffc000';
}
return h('div', {
style:style
} ,params.row.qxdj)
}
},
],
}
好了,组件都发过去了,再来谈谈这一套的实现原理,优点,和不足之处吧:
优点:1、可以完美的将iview的render那种模式应用在element-ui的table 中
2、可以使用头部slot来更换头部的内容和元素,比如写一个下拉的组件,然后放进去是可以的,写一个popover的弹框也 是可以的
3、也有内容slot,放进去可以写入操作这类型的特殊组件
不足之处:因为,我这里是将slot单独都拿出来封装(业务需要),没办法实现slot的再次封装,在slot里面必须写死他的prop 值,不然拿不到数据;还有,注意不要在内部设置element自带的高度,经过测试当数据量特别大,页面会卡死,
这个组件的封装就到这里:
使用步骤:
1、
2、
3、
4、
5、
好了,到这里就大功告成了,欢迎小伙伴们对这个进行再次优化,或者前来交流
GitHub 加速计划 / eleme / element
10
1
下载
A Vue.js 2.0 UI Toolkit for Web
最近提交(Master分支:4 个月前 )
c345bb45
8 个月前
a07f3a59
* Update transition.md
* Update table.md
* Update transition.md
* Update table.md
* Update transition.md
* Update table.md
* Update table.md
* Update transition.md
* Update popover.md 8 个月前
更多推荐
已为社区贡献46条内容
所有评论(0)