基于vue+element,用的都是element自带的方法,存在一些问题,仅提供部分参考,调用要加宽高
前言
提示:
想封装一个符合自己经常写代码的逻辑样式的组件,之前师傅用iview写了一个一样的,但是iview方法太少,尤其是表头部分很难自定义,所以有一些bug很难解决,但是element自带表头编辑功能,解决了最难的部分。
提示:以下是本篇文章正文内容,下面案例仅供参考,bug太多不要怪我,我这里没有大量测试,数据量也小,有些隐形bug可能我没找到,欢迎提出。
一、基本逻辑
element的table的列是这样写的:
<el-table
:data="tableData"
style="width: 100%">
<el-table-column
prop="date"
label="日期"
width="180">
</el-table-column>
<el-table-column
prop="name"
label="姓名"
width="180">
</el-table-column>
<el-table-column
prop="address"
label="地址">
</el-table-column>
</el-table>
而iview是这样的:
columns1: [
{
title: 'Name',
key: 'name'
},
{
title: 'Age',
key: 'age'
},
{
title: 'Address',
key: 'address'
}
],
这两种我们需要后一种,这样方便在js里操作数据,表头则通过element定义成自己需要的样式,表头自定义方法element自带,用插槽。
<template slot="header" slot-scope="scope">
<div style="display: flex;flex-direction: row">
<div>{{item.label}}</div>
<el-button size="mini" type="text" @click="addColumn(item,scope)">+</el-button>
<el-button size="mini" type="text" @click="deleteColumn(item,scope)">-</el-button>
</div>
</template>
二、功能实现
1.行
先搞最简单的行新增删除,我基本都是通过splice实现的,新增的方法是当前行向下增加,
后面那个isEdit是编辑时用的,如果只是新增删除则不需要,删掉花括号里的内容就好(别删花括号),花括号相当于表格数据的空数据,数据结构类似[ {}, {}, {} ]这样。如果想加在当前行上边,把+1删掉就好,但是删除的时候只需要scope.$index,毕竟不能删当前行结果别的行没了。
删除
this.tableData.splice(scope.$index, 1)
这种方法数据是实时的(我没做监听或者数据重新渲染)
2.列
一开始列我也是这么想的,但是有渲染错误,console的数据与显示的不同,尤其是新增两个及以上时,console的值没问题,就是没有及时渲染,尤其不能像tableData的数据直接传{},这会让tablecolumn显示错序,如果没值可以传{ label: '', prop: '' },虽然也是空的,但是神奇的没报错,如果想在列里加数据,可以加个dialog,label就是显示值,value我绑的是prop,这俩值理论上应该做个校验。
新增列
this.column.splice(this.columnCopyData.$index + 1, 0, this.formItem)
this.formItem = {}
如果不清空formItem则会导致column值乱序,甚至出现删除值覆盖前一列值的现象,这时需要将列表重新渲染,用nextTick就行
删除
this.column.splice(scope.$index, 1) // 删除当前行
let arr = [] // 声明新数组暂存表格列数据
arr = this.column
this.column = [] // 先清空列,再赋值重新渲染
this.$nextTick(function() {
this.column = arr
})
总结
这只是一个基本的框架,只有部分逻辑,如果使用,请确保测试过了,data部分随便加,column部分要重新渲染,column的新增值我通过dialog增加的
源码
html:
表格
<el-table :data="tableData">
<el-table-column
v-for="(item,index) in column"
:key="index"
:label="item.label"
>
<template slot="header" slot-scope="scope">
<div style="display: flex;flex-direction: row">
<div>{{item.label}}</div>
<el-button size="mini" type="text" @click="addColumn(item,scope)">+</el-button>
<el-button size="mini" type="text" @click="deleteColumn(item,scope)">-</el-button>
</div>
</template>
<template slot-scope="scope">
<div v-if="!scope.row.isEdit">{{scope.row[item.prop]}}</div>
<el-input v-if="scope.row.isEdit" v-model="scope.row[item.prop]"></el-input>
</template>
</el-table-column>
<el-table-column
label="操作"
align="center"
width="300px"
>
<template slot-scope="scope">
<el-button size="mini" type="primary" @click="addRow(scope)">新增行</el-button>
<el-button size="mini" type="danger" @click="deleteRow(scope)">删除行</el-button>
<el-button size="mini" v-if="scope.row.isEdit" type="success" @click="saveRow(scope)">保存</el-button>
<el-button size="mini" v-if="!scope.row.isEdit" type="warning" @click="editRow(scope)">编辑</el-button>
</template>
</el-table-column>
</el-table>
表格列新增弹框
<el-dialog title="新增列" :visible.sync="dialogVisible">
<el-form :model="formItem">
<el-form-item label="label">
<el-input v-model="formItem.label" placeholder=""></el-input>
</el-form-item>
<el-form-item label="value">
<el-input v-model="formItem.prop" placeholder=""></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="onsubmit">确 定</el-button>
</span>
</el-dialog>
js:
data:
dialogVisible: false,
formItem: {},
columnCopyData: {},
tableData: [
{ name: '123', age: 12, sex: '男', isEdit: false },
{ name: '123', age: 12, sex: '男', isEdit: false },
{ name: '123', age: 12, sex: '男', isEdit: false }
],
column: [
{ label: '姓名', prop: 'name' },
{ label: '年龄', prop: 'age' },
{ label: '性别', prop: 'sex' }
]
方法:
// 新增行
addRow(scope) {
console.log(scope)
this.tableData.splice(scope.$index + 1, 0, { isEdit: false })
},
// 保存行
saveRow(scope) {
scope.row.isEdit = false
},
// 删除行
deleteRow(scope) {
this.tableData.splice(scope.$index, 1)
},
// 编辑行
editRow(scope) {
scope.row.isEdit = true
},
// 新增列
addColumn(item, scope) {
console.log(item, scope)
this.dialogVisible = true
this.columnCopyData = scope
// this.column.splice(scope.$index + 1, 0, this.formItem)
// this.dialogVisible = false
console.log(this.column)
},
// 保存列
onsubmit() {
this.column.splice(this.columnCopyData.$index + 1, 0, this.formItem)
this.formItem = {}
this.dialogVisible = false
},
// 删除列
deleteColumn(item, scope) {
console.log(scope)
this.column.splice(scope.$index, 1)
let arr = []
arr = this.column
this.column = []
this.$nextTick(function() {
this.column = arr
})
console.log('减', this.column)
}