Element?Table行的動(dòng)態(tài)合并及數(shù)據(jù)編輯示例
正文
先描述一下需求,看下圖

1:動(dòng)態(tài)合并行,如圖所示,第一列全部合并,第二列和第三列第四列根據(jù)名稱進(jìn)行合并
2:可以動(dòng)態(tài)編輯第三列和第四列,并且只能編輯屬于此合并行的第三列和第四列,比如第一個(gè)編輯按鈕點(diǎn)擊后,只有前三行可以編輯
3:第一列的數(shù)據(jù)是根據(jù)第三列相加得來(lái)的
4:點(diǎn)擊快捷填寫,可以快速填寫第三列和第四列
思路
1:第二列和第三列第四列根據(jù)名稱進(jìn)行合并
后臺(tái)根據(jù)名稱進(jìn)行排序,前臺(tái)通過(guò)循環(huán)解析名稱來(lái)知道哪一行需要合并,這個(gè)從網(wǎng)上找了一個(gè)自己改了下。
第一列特殊情況根據(jù)上面的思路做簡(jiǎn)單修改
element代碼: span-method="cellMerge"
<el-table
border
:data="tableData3"
height="100%"
width="100%"
:cell-style="cellStyle"
:row-style="getRowClass"
:header-row-style="getRowClass"
:header-cell-style="getRowClass"
:span-method="cellMerge"
> vue代碼:
//合并單元格,此方法需要后臺(tái)進(jìn)行名字進(jìn)行排序
cellMerge({ row, column, rowIndex, columnIndex }) {
let length = this.tableData3.length;
//第0列比較特殊,單獨(dú)合并
if (columnIndex === 0) {
const _row = this.spanArrOne[rowIndex];
const _col = _row > 0 ? 1 : 0;
return {
rowspan: _row,
colspan: _col
};
}
//1 2 5列進(jìn)行合并
if (columnIndex === 1 || columnIndex === 2 || columnIndex === 5) {
const _row = this.spanArr[rowIndex];
const _col = _row > 0 ? 1 : 0;
return {
rowspan: _row,
colspan: _col
};
}
},
//1 2 5列合并的數(shù)據(jù)
getSpanArr(data) {
for (var i = 0; i < data.length; i++) {
if (i === 0) {
this.spanArr.push(1);
this.pos = 0;
} else {
// 判斷當(dāng)前元素與上一個(gè)元素是否相同
if (data[i].name === data[i - 1].name) {
this.spanArr[this.pos] += 1; //需要合并的行數(shù)
this.spanArr.push(0); //新增被合并的行
} else {
this.spanArr.push(1);
this.pos = i; //新的需要合并的第幾行數(shù)
}
}
}
},
//0列合并的數(shù)據(jù)
getSpanArrOne(data) {
for (var i = 0; i < data.length; i++) {
if (i === 0) {
this.spanArrOne.push(1);
this.posOne = 0;
} else {
this.spanArrOne[this.posOne] += 1; //需要合并的行數(shù)
this.spanArrOne.push(0); //新增被合并的行
}
}
console.log(this.spanArrOne, " this.spanArrOne");
},2:可以動(dòng)態(tài)編輯第三列和第四列解決
添加template模塊,里面添加input輸入框和span標(biāo)簽,通過(guò)屬性進(jìn)行控制,我是通過(guò)取出后臺(tái)數(shù)據(jù),遍歷后添加了自定義屬性editing來(lái)控制的,為了只能編輯通過(guò)名稱合并的第三列和第四列,我添加了屬性flagNum,名字相同的行flagNum一樣,我這邊打印出來(lái)的是 0-2行是0 3到5行是3 6到9行是6以此類推,可以發(fā)現(xiàn)其規(guī)律就是第一個(gè)開頭的行,當(dāng)你點(diǎn)擊第一個(gè)編輯按鈕的時(shí)候,傳的index就是0,所以根據(jù)flagNum匹配0-2行可以編輯,下面的是一樣的邏輯
element代碼;
<el-table-column prop="value1" label="XXX" min-width="15%" align="center">
<template slot-scope="scope">
<template v-if="scope.row.editing">
<el-input class="edit-input" v-model="scope.row.value1"></el-input>
</template>
<span v-else>{{ scope.row.value1 }}</span>
</template>
</el-table-column>vue代碼:
//判斷可編輯作用域 用到的數(shù)據(jù)spanArr4Edit
getSpanArr4Edit(data) {
let ctx = this;
var flagNum = 0;
for (var i = 0; i < data.length; i++) {
//首先不能編輯
ctx.$set(data[i], "editing", false);
if (i === 0) {
ctx.spanArr4Edit.push(flagNum);
} else {
// 判斷當(dāng)前元素與上一個(gè)元素是否相同
if (data[i].name === data[i - 1].name) {
ctx.spanArr4Edit.push(flagNum); //還是同一個(gè)記錄
} else {
ctx.spanArr4Edit.push(i);
flagNum = i;
}
}
//與編輯相對(duì)應(yīng)
ctx.$set(data[i], "flagNum", flagNum);
}
//最終賦值
ctx.tableData3 = data;
console.log(ctx.spanArr4Edit, "this.spanArr4Edit");
},
handleEdit(index, row) {
let ctx = this;
this.setEditFlag(index, 1);
console.log(index);
},
/編輯輸入框顯示與隱藏0 隱藏 1顯示
setEditFlag: function(index, flag) {
let ctx = this;
let datalength = ctx.tableData3.length;
let flagNum = ctx.spanArr4Edit[index];
for (let i = 0; i < datalength; i++) {
if (flag == 1) {
if (flagNum === ctx.tableData3[i].flagNum) {
//循環(huán)遍歷改變可編輯的標(biāo)記
this.$set(ctx.tableData3[i], "editing", true);
}
} else {
//循環(huán)遍歷改變可編輯的標(biāo)記
this.$set(ctx.tableData3[i], "editing", false);
}
}
}3:第一列的數(shù)據(jù)是根據(jù)第三列相加得來(lái)的
可以用監(jiān)聽器深度監(jiān)聽后臺(tái)傳過(guò)來(lái)的數(shù)據(jù)
代碼:
watch: {
tableData3: {
handler(newValue, oldValue) {
let ctx = this;
let length = oldValue.length;
var num = 0;
if (length > 0) {
for (let i = 0; i < length; i++) {
//取出編輯后的對(duì)象數(shù)據(jù)
num = Number(num) + Number(ctx.tableData3[i].value1);
}
if (num != 0) {
//賦值對(duì)象數(shù)據(jù)
ctx.tableData3[0].all = num;
} else {
ctx.tableData3[0].all = "";
}
}
},
deep: true //深度監(jiān)聽對(duì)象里面的屬性
}
},4:彈出個(gè)輸入框
此邏輯比較簡(jiǎn)單,就是彈出個(gè)輸入框,點(diǎn)擊確認(rèn)把值帶到這個(gè)頁(yè)面進(jìn)行填寫
直接上代碼:
//快捷填寫保存
addSubmit: function() {
let ctx = this;
//賦值數(shù)據(jù),取出哪一行需要進(jìn)行賦值
let idx = this.quickFlag;
let datalength = ctx.tableData3.length;
//每次快捷填寫某一個(gè)區(qū)域,所以此變量在此定義
var initFlag = 0;
for (let i = 0; i < datalength; i++) {
if (idx === ctx.tableData3[i].flagNum) {
if (initFlag == 0) {
//value1 只賦值一次就行
this.$set(ctx.tableData3[i], "value1", this.addform.w);
}
initFlag++;
this.$set(ctx.tableData3[i], "value2", this.addform.q);
}
}
this.dialogQuick = false;
ctx.$message.success("操作成功");
console.log(this.addform, "this.addform");
},-----------------------------------分割線------------------------------------------------
完整代碼
<template>
<div class="waterApplyTable">
<el-table
border
:data="tableData3"
height="100%"
width="100%"
:cell-style="cellStyle"
:row-style="getRowClass"
:header-row-style="getRowClass"
:header-cell-style="getRowClass"
:span-method="cellMerge"
>
<el-table-column prop="title" :label="title" align="center">
<el-table-column prop="all" label="xx" min-width="20%">
<template slot-scope="scope">
<span>{{ scope.row.all }}</span>
</template>
</el-table-column>
<el-table-column prop="name" label="xx" min-width="15%" align="center" show-overflow-tooltip></el-table-column>
<el-table-column prop="value1" label="xx" min-width="15%" align="center">
<template slot-scope="scope">
<template v-if="scope.row.editing">
<el-input class="edit-input" v-model="scope.row.value1"></el-input>
</template>
<span v-else>{{ scope.row.value1 }}</span>
</template>
</el-table-column>
<el-table-column prop="value2" label="xx" min-width="15%" align="center">
<template slot-scope="scope">
<template v-if="scope.row.editing">
<el-input class="edit-input" v-model="scope.row.value2"></el-input>
</template>
<span v-else>{{ scope.row.value2 }}</span>
</template>
</el-table-column>
<el-table-column prop="value3" label="xx" min-width="15%" align="center"></el-table-column>
<el-table-column prop="editing" label="操作" min-width="20%" align="center">
<template slot-scope="scope">
<el-button
type="primary"
v-if="!scope.row.editing"
@click.native="handleEdit(scope.$index, scope.row)"
>編輯</el-button>
<el-button type="primary" v-else @click.native="savemodify(scope.$index, scope.row)">保存</el-button>
<el-button type="primary" @click.native="clickTodo(scope.$index, scope.row)">快捷填寫</el-button>
</template>
</el-table-column>
</el-table-column>
</el-table>
<el-dialog
class="dialog"
:visible="dialogQuick"
top="15vh"
@close="dialogQuickClose"
width="20%"
title="快捷填寫"
:append-to-body="true"
>
<el-form :model="addform" class="demo-form-inline">
<el-form-item label="x">
<el-input v-model.trim="addform.w"></el-input>
</el-form-item>
<el-form-item label="xx">
<el-input v-model.trim="addform.q"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click.native="addSubmit">確定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
name: "waterApplyTable",
props: {
total: {
type: Number,
default: 100
}
},
data() {
return {
rules: {},
page: 1,
pageSize: 20,
pageCount: 10,
formInline: {
area: "青島市",
year: "2018-2019"
},
tableData3: [],
dialogQuick: false,
addform: {},
spanArr: [],
pos: "",
spanArrOne: [],
posOne: "",
spanArr4Edit: [],
pos4Edit: "",
//快捷填寫flag,記錄哪一行數(shù)據(jù)的快捷填寫
quickFlag: "",
title:'我是表頭',
};
},
watch: {
tableData3: {
handler(newValue, oldValue) {
let ctx = this;
let length = oldValue.length;
var num = 0;
if (length > 0) {
for (let i = 0; i < length; i++) {
num = Number(num) + Number(ctx.tableData3[i].value1);
}
if (num != 0) {
ctx.tableData3[0].all = num;
} else {
ctx.tableData3[0].all = "";
}
}
},
//immediate: true,
deep: true //深度監(jiān)聽對(duì)象里面的屬性
}
},
created() {
this.getData();
},
mounted() {
// this.getData();
},
methods: {
getData() {
this.getTableDataList();
},
// 列表,
getTableDataList() {
let ctx = this;
// ctx.$api
// .getTableDataList()
// .then(res => {
// ctx.total = res.totalRows;
// ctx.pageCount = ctx.total / ctx.pageSize + 1;
// ctx.tableData = res.rows;
// })
// .catch(() => {
// });
let _data = [
{
all: "",
name: "名字1",
value1: "",
value2: "",
value3: "2017年-10月"
},
{
all: "",
name: "名字1",
value1: "",
value2: "",
value3: "2017年-11月"
},
{
all: "",
name: "名字1",
value1: "",
value2: "",
value3: "2017年-12月"
},
{
all: "",
name: "名字2",
value1: "",
value2: "",
value3: "2017年-10月"
},
{
all: "",
name: "名字2",
value1: "",
value2: "",
value3: "2017年-11月"
},
{
all: "",
name: "名字2",
value1: "",
value2: "",
value3: "2017年-12月"
},
{
all: "",
name: "名字3",
value1: "",
value2: "",
value3: "2017年-10月"
},
{
all: "",
name: "名字3",
value1: "",
value2: "",
value3: "2017年-11月"
},
{
all: "",
name: "名字3",
value1: "",
value2: "",
value3: "2017年-12月"
},
{
all: "",
name: "名字4",
value1: "",
value2: "",
value3: "2017年-10月"
},
{
all: "",
name: "名字4",
value1: "",
value2: "",
value3: "2017年-11月"
},
{
all: "",
name: "名字4",
value1: "",
value2: "",
value3: "2017年-12月"
}
];
//進(jìn)行賦值,為了后面編輯用,此方法位置不要?jiǎng)?
ctx.getSpanArr4Edit(_data);
console.log(ctx.tableData3, "ctx.tableData3");
ctx.getSpanArr(ctx.tableData3);
ctx.getSpanArrOne(ctx.tableData3);
},
//改變分頁(yè)事件已辦理
clickChangePage(currPage) {
this.getGateStationList(currPage);
},
cellStyle({ row, column, rowIndex, columnIndex }) {
return "padding:0px";
},
getRowClass({ row, column, rowIndex, columnIndex }) {
return "height:0";
},
searchData: function() {
let searchVal = this.formInline.searchVal;
},
setClass(gateState) {
if (gateState == 0) {
return "stateClass-a";
}
return "stateClass-b";
},
dialogQuickClose: function() {
this.dialogQuick = false;
},
//前行row、當(dāng)前列column、當(dāng)前行號(hào)rowIndex、當(dāng)前列號(hào)columnIndex四個(gè)屬性
//index 0開始
objectSpanMethod: function({ row, column, rowIndex, columnIndex }) {
let length = this.tableData3.length - 1;
// //合并第一列
// if (columnIndex === 0) {
// console.log(columnIndex, "columnIndex");
// alert(columnIndex);
// if (rowIndex % length === 0) {
// return {
// rowspan: length + 1,
// colspan: 1
// };
// } else {
// return {
// rowspan: 0,
// colspan: 0
// };
// }
// }
//合并第一列
if (columnIndex === 0) {
alert(columnIndex);
if (rowIndex % 2 === 0) {
return {
rowspan: 2,
colspan: 1
};
} else {
return {
rowspan: 0,
colspan: 0
};
}
}
//合并第二三列
},
//合并單元格,此方法需要后臺(tái)進(jìn)行名字進(jìn)行排序
cellMerge({ row, column, rowIndex, columnIndex }) {
let length = this.tableData3.length;
//第0列比較特殊,單獨(dú)合并
if (columnIndex === 0) {
const _row = this.spanArrOne[rowIndex];
const _col = _row > 0 ? 1 : 0;
return {
rowspan: _row,
colspan: _col
};
}
//1 2 5列進(jìn)行合并
if (columnIndex === 1 || columnIndex === 2 || columnIndex === 5) {
const _row = this.spanArr[rowIndex];
const _col = _row > 0 ? 1 : 0;
return {
rowspan: _row,
colspan: _col
};
}
},
//1 2 5列合并的數(shù)據(jù)
getSpanArr(data) {
for (var i = 0; i < data.length; i++) {
if (i === 0) {
this.spanArr.push(1);
this.pos = 0;
} else {
// 判斷當(dāng)前元素與上一個(gè)元素是否相同
if (data[i].name === data[i - 1].name) {
this.spanArr[this.pos] += 1; //需要合并的行數(shù)
this.spanArr.push(0); //新增被合并的行
} else {
this.spanArr.push(1);
this.pos = i; //新的需要合并的第幾行數(shù)
}
}
}
},
//0列合并的數(shù)據(jù)
getSpanArrOne(data) {
for (var i = 0; i < data.length; i++) {
if (i === 0) {
this.spanArrOne.push(1);
this.posOne = 0;
} else {
this.spanArrOne[this.posOne] += 1; //需要合并的行數(shù)
this.spanArrOne.push(0); //新增被合并的行
}
}
console.log(this.spanArrOne, " this.spanArrOne");
},
//編輯用到的數(shù)據(jù)
getSpanArr4Edit(data) {
let ctx = this;
var flagNum = 0;
for (var i = 0; i < data.length; i++) {
//首先不能編輯
ctx.$set(data[i], "editing", false);
if (i === 0) {
ctx.spanArr4Edit.push(flagNum);
} else {
// 判斷當(dāng)前元素與上一個(gè)元素是否相同
if (data[i].name === data[i - 1].name) {
ctx.spanArr4Edit.push(flagNum); //還是同一個(gè)記錄
} else {
ctx.spanArr4Edit.push(i);
flagNum = i;
}
}
//與編輯相對(duì)應(yīng)
ctx.$set(data[i], "flagNum", flagNum);
}
//最終賦值
ctx.tableData3 = data;
console.log(ctx.spanArr4Edit, "this.spanArr4Edit");
},
//快捷填寫
clickTodo: function(index, row) {
this.dialogQuick = true;
this.quickFlag = index;
this.addform = {};
},
//快捷填寫保存
addSubmit: function() {
let ctx = this;
//賦值數(shù)據(jù),取出哪一行需要進(jìn)行賦值
let idx = this.quickFlag;
let datalength = ctx.tableData3.length;
//每次快捷填寫某一個(gè)分水口,所以此變量在此定義
var initFlag = 0;
for (let i = 0; i < datalength; i++) {
if (idx === ctx.tableData3[i].flagNum) {
if (initFlag == 0) {
//value1 只賦值一次就行
this.$set(ctx.tableData3[i], "value1", this.addform.w);
}
initFlag++;
this.$set(ctx.tableData3[i], "value2", this.addform.q);
}
}
this.dialogQuick = false;
ctx.$message.success("操作成功");
console.log(this.addform, "this.addform");
},
handleEdit(index, row) {
let ctx = this;
this.setEditFlag(index, 1);
console.log(index);
// this.prevValue = JSON.parse(JSON.stringify(row));//保存之前的數(shù)據(jù)
},
handleCancle(index, row) {
row.editing = false;
// let prevContent = this.prevValue.bookname;
// this.$set(row,"bookname",prevContent);
},
savemodify(index, row) {
this.setEditFlag(index, 0);
console.log(row, "row");
console.log(this.tableData3, "改變后的table數(shù)據(jù)");
console.log(
JSON.stringify(this.tableData3),
"JSON.stringify(this.tableData3)"
);
},
//提交數(shù)據(jù)到后臺(tái)
submitToServe() {
let ctx = this;
let dataResult = JSON.parse(JSON.stringify(this.tableData3));
var result = 0;
//調(diào)用后臺(tái)保存方法
// ctx.$api.addWaterApply(dataResult).then(res => {
// if (res.code == "0") {
// result =1;
// }
// });
console.log(dataResult, "提交到后臺(tái)的數(shù)據(jù)");
//return result;
return 1;
},
//編輯輸入框顯示與隱藏0 隱藏 1顯示
setEditFlag: function(index, flag) {
let ctx = this;
let datalength = ctx.tableData3.length;
let flagNum = ctx.spanArr4Edit[index];
for (let i = 0; i < datalength; i++) {
if (flag == 1) {
if (flagNum === ctx.tableData3[i].flagNum) {
//循環(huán)遍歷改變可編輯的標(biāo)記
this.$set(ctx.tableData3[i], "editing", true);
}
} else {
//循環(huán)遍歷改變可編輯的標(biāo)記
this.$set(ctx.tableData3[i], "editing", false);
}
}
}
},
filters: {
iswarnFlt(val) {
return val == 0 ? "否" : "是";
}
}
};
</script>
<style lang="scss" scoped>
.waterApplyTable {
height: 100%;
}
</style>以上就是Element Table行的動(dòng)態(tài)合并及數(shù)據(jù)編輯示例的詳細(xì)內(nèi)容,更多關(guān)于Element Table行動(dòng)態(tài)合并編輯的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- vue+elementui實(shí)現(xiàn)動(dòng)態(tài)添加行/可編輯的table
- 關(guān)于vue中element-ui?form或table?lable換行的問(wèn)題
- vue+element獲取el-table某行的下標(biāo),根據(jù)下標(biāo)操作數(shù)組對(duì)象方式
- vuejs element table 表格添加行,修改,單獨(dú)刪除行,批量刪除行操作
- element-ui table行點(diǎn)擊獲取行索引(index)并利用索引更換行順序
- Elementui表格組件+sortablejs實(shí)現(xiàn)行拖拽排序的示例代碼
相關(guān)文章
vue組件和iframe頁(yè)面的相互傳參問(wèn)題及解決
這篇文章主要介紹了vue組件和iframe頁(yè)面的相互傳參問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05
Vue.js實(shí)戰(zhàn)之通過(guò)監(jiān)聽滾動(dòng)事件實(shí)現(xiàn)動(dòng)態(tài)錨點(diǎn)
監(jiān)聽事件是我們?cè)谑褂胿ue.js的時(shí)候經(jīng)常使用的一個(gè)功能,下面這篇文章主要介紹了Vue.js實(shí)戰(zhàn)之通過(guò)監(jiān)聽滾動(dòng)事件實(shí)現(xiàn)動(dòng)態(tài)錨點(diǎn) 的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),相信對(duì)大家具有一定的參考價(jià)值,需要的朋友們下面來(lái)一起看看吧。2017-04-04
vue實(shí)現(xiàn)組件跟隨鼠標(biāo)位置彈出效果(示例代碼)
這篇文章主要介紹了vue中實(shí)現(xiàn)組件跟隨鼠標(biāo)位置彈出效果,本文通過(guò)圖文示例代碼相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-02-02
使用vscode格式化文檔無(wú)效的解決辦法(vue代碼格式化文檔無(wú)效)
這篇文章主要給大家介紹了關(guān)于使用vscode格式化文檔無(wú)效的解決辦法,也就是vue代碼格式化文檔無(wú)效,這是最近突然遇到的一個(gè)問(wèn)題,這里給大家介紹一下解決的辦法,需要的朋友可以參考下2023-08-08
vue項(xiàng)目使用js監(jiān)聽瀏覽器關(guān)閉、刷新及后退事件的方法
這篇文章主要給大家介紹了關(guān)于vue項(xiàng)目使用js監(jiān)聽瀏覽器關(guān)閉、刷新及后退事件的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用vue具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-09-09
webpack4打包vue前端多頁(yè)面項(xiàng)目
這篇文章主要介紹了webpack4打包vue前端多頁(yè)面項(xiàng)目的相關(guān)知識(shí),非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-09-09
nginx+vue.js實(shí)現(xiàn)前后端分離的示例代碼
這篇文章主要介紹了nginx+vue.js實(shí)現(xiàn)前后端分離的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-02-02

