说明
在使用 element ui 表格组件的时候频繁的引用,相同的业务代码反复,所以萌生了要简易封装一下的想法,做项目的过程中又有了表格单元格可编辑的需求,因此总结记录一下实现过程。
实现
一、el-table表格封装成公共组件
1.创建表格主体(也是即将抽离成公共组件)文件:listEdit.vue (文件名随意)
template部分
<template>
<el-table
ref="listEdit"
:data="tableData"
>
<!-- fixed:列是否固定在左侧或者右侧,true 表示固定在左侧;show-overflow-tooltip: 当内容过长被隐藏时显示 tooltip -->
<el-table-column fixed type="index" width="45" label="序号" show-overflow-tooltip/>
<!-- 这里用插槽来写表格列,为了方便在调用组件的时候更方便自定义表格列 -->
<slot name="column">
<!-- sortable:排序 -->
<el-table-column v-for="(item,index) of columnList" :key="index" :prop="item.prop" :label="item.label" sortable show-overflow-tooltip/>
</slot>
</el-table>
</template>
script部分
<script>
export default {
name: "ListEdit",
props: {
tableData: {
type: Array,default:() => []
},
columnList: {
type: Array,default:() => []
},
}
}
</script>
基础文件准备完毕 ,接下来对表格功能进一步完善。
2.表格改造
①给表格增加上一些属性设置
height:Table 的高度
highlight-current-row:高亮当前行
border:是否带有纵向边框
header-cell-style:表头单元格样式
cell-style:单元格的 style 的回调方法
row-class-name:行的 className 的回调方法
row-style:行的 style 的回调方法
②给表格增加上一些事件方法
@row-click="rowClick" // 行单击事件
@selection-change="handleSelectionChange" // 选择事件
<template>
<el-table
ref="listEdit"
:data="tableData"
highlight-current-row
border
:height="tableHeight"
style="width:100%"
:header-cell-style="{
color: '#333',
background: '#f8f8f9',
padding: '0px',
fontSize: '12px',
}"
:cell-style="{ padding: '0px', height: '22px', cursor: 'pointer' }"
:row-class-name="rowClassName"
:row-style="rowStyle"
@row-click="rowClick"
@selection-change="handleSelectionChange"
>
<!-- fixed:列是否固定在左侧或者右侧,true 表示固定在左侧;show-overflow-tooltip: 当内容过长被隐藏时显示 tooltip -->
<el-table-column fixed type="index" width="45" label="序号" show-overflow-tooltip/>
<!-- 这里用插槽来写表格列,为了方便在调用组件的时候更方便自定义表格列 -->
<slot name="column">
<!-- sortable:排序 -->
<el-table-column v-for="(item,index) of columnList" :key="index" :prop="item.prop" :label="item.label" sortable show-overflow-tooltip/>
</slot>
</el-table>
</template>
<script>
export default {
name: "ListEdit",
props: {
tableHeight: {
type: Number,default: () => 300
},
tableData: {
type: Array,default:() => []
},
columnList: {
type: Array,default:() => []
},
},
methods: {
rowClassName({}){ // 行class
const className = 'resetClass'
return className
},
rowStyle({ row, rowIndex}){ // 行样式
const styleJson = {}
// console.log('设置行样式的当前行:',row);
if (row.isExist === '1') { // 根据当前行的属性来判断,并设置当前行样式
styleJson.color = '#BCBEC2'
styleJson.background = '#F4F4F5'
return styleJson
} else {
return ''
}
},
rowClick(row) { // 行单击事件
this.$emit("callBackFun", {
type: 'rowClick',
data: row
})
},
handleSelectionChange(val) { // 行选 change 事件
this.$emit("callBackFun", {
type: 'select',
data: val
})
},
unSelected() {
this.$refs.listEdit.setCurrentRow() // setCurrentRow() 设定某行为选中行,不加参数则取消目前高亮行的选中状态
},
},
}
</script>
③给表格增加样式控制
<style lang="scss" scoped>
// 鼠标移入高亮
::v-deep .el-table__body tr.hover-row>td {
background-color: #fff2e0 !important;
// color: #fff;
}
// 表格点击高亮
::v-deep .el-table__body tr.current-row>td {
background-color: #FBD9A7 !important;
// color: #fff;
}
// -----------------------------------------------------------------------------------------
/**
可以使用CSS的text-overflow属性来实现表格超出部分省略号显示,并且鼠标移入完整显示的效果
1.首先,在表格的样式中添加以下CSS样式
2.然后,在表格的列定义中,添加show-overflow-tooltip属性,用于鼠标移入时显示完整内容的提示:
*/
::v-deep .el-table__body-wrapper .cell {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
height: 100%;
}
::v-deep .el-table__body-wrapper .cell:hover {
overflow: visible;
white-space: normal;
}
// -----------------------------------------------------------------------------------------
</style>
至此表格组件封装完毕。
二、组件使用
1.引入
import ListEdit from "@/components/BC-wheelH/zdy-table/elbox/listEdit.vue";
2.声明
components: {
ListEdit
},
3.使用
template
<ListEdit
:tableHeight="tableHeight"
:tableData="tableData"
@callBackFun="callBackFun"
>
<!-- 这里使用插槽 v-slot 的值 一定要和组件中 slot 标签 name 属性值相对应 -->
<template v-slot:column>
<el-table-column fixed type="selection" width="45" show-overflow-tooltip/>
</template>
</ListEdit>
script
<script>
import ListEdit from "@/components/BC-wheelH/zdy-table/elbox/listEdit.vue";
export default {
components: {
ListEdit
},
data() {
return {
tableHeight: 600,
tableData: [],
};
},
methods: {
callBackFun(val){
switch (val.type) {
case 'rowClick': // 行单击事件
break;
case 'select': // 行选 change 事件
break;
default:
break;
}
}
},
};
</script>
4. 优化
表格的高度height值不方便设置一个固定值所以:
①在组件外包裹一层标签盒子
<div resf="mainBox" style="height:100%">
<ListEdit
:tableHeight="tableHeight"
/>
</div>
②组件盒子高度值设100%再获取标签盒子的高度传值进组件,这样盒子标签是什么高度表格就是什么高度
// 获取主体高度(传值给表格撑起高度)
this.tableHeight = this.$refs.mainBox.clientHeight
三、实现单元格可编辑
1.思路
想实现能编辑输入,首先就想到了表单,所以实现方法就时在表格列写插槽 input 来承载键盘的输入
2.实现
template 部分
<ListEdit
:tableHeight="tableHeight"
:tableData="tableData"
>
<template v-slot:column>
<el-table-column prop="lengthValue" label="余量长度(mm)" width="120" show-overflow-tooltip>
<template slot-scope="scope">
<!-- class 动态绑定 bgf 根据 lengthValueTF 的值来判断 lengthValue 的值合不合理 -->
<input :class="{'bgf': !scope.row.lengthValueTF}" v-model="scope.row.lengthValue" size="mini" @blur="inputBlur(scope,scope.row.lengthValue)" style="width:100%;height:100%;border:none !important;background:#FBD9A7;outline:none" />
</template>
</el-table-column>
</template>
</ListEdit>
script 部分
<script>
export default {
data() {
return {
tableData: [
{ lengthValue:100,lengthValueTF:false }
],
};
},
methods: {
inputBlur(val,value){
// console.log(val);
},
},
};
</script>
style 部分
.bgf{
background-color: red !important;
color: #ffffff;
}
3.优化
用到表单了就需要校验,所以要与之配套的加入校验方法
①新建 check.js 文件封装校验方法
function checkFun(check,value,callback){ // 校验函数
// console.log(check,value,callback);
if (check === 'integer0+') {
let reg = /^([1-9]\d*|[0]{1,1})$/; // 正整数(包含0)
// console.log(!reg.test(value));
if (!reg.test(value)) {
// console.log('假');
callback(new Error('请输入正整数'))
} else {
// console.log('真');
callback()
}
}
if (check === 'integer+') {
let reg = /^([1-9][0-9]*)$/; // 正整数
// console.log(!reg.test(value));
if (!reg.test(value)) {
// console.log('假');
callback(new Error('请输入正整数'))
} else {
// console.log('真');
callback()
}
}
if (check === 'nonempty') {
if (value === '' || value == null || value == undefined) {
callback(new Error('不能为空'));
} else {
callback();
}
}
}
export default {
checkFun
};
②引入校验方法,并且在input回调方法里对输入进行校验
<script>
import check from "@/components/BC-wheelH/function/check.js"
export default {
data() {
return {
tableData: [
{ lengthValue:100,lengthValueTF:false }
],
};
},
methods: {
inputBlur(val,value){
// console.log(val);
check.checkFun('integer0+',value,(err) => {
if (err) { // 校验报错
// 单元格加状态来提示当前此数据不合格
// console.log(err.message);
this.$message.error('第 ' + (val.$index+1) + ' 行请输入正整数');
if (val.column.property === "lengthValue") {
// 改变校验结果标识
this.tableData[val.$index].lengthValue= false
}
} else {
if (val.column.property === "margin") {
// 改变校验结果标识
this.tableData[val.$index].lengthValue= true
}
// console.log('输入有效');
}
} )
},
},
};
</script>