1、技术概述
Vxe-table是一个Vue的表格插件,我们项目需要实现填写表格的功能,于是我就找到了这个插件。难点在于,我觉得这个插件的手册写得不是很好,很多地方要自己研究。
2、技术详述
简单来说,Vxe-table由三个部分组成,表格样式,表格数据,表格方法。
表格样式
表格样式由参数来控制,表格要调用的方法也是写在参数上的。
<div id="OuterEditableTable" class="container col-md-10 offset-md-1" style="margin: 50px auto;">
<h2>{{this.$data.title}}</h2>
<vxe-grid
v-if="ready"
border
keep-source
resizable
ref="xTable"
:columns="tableColumn"<!-- 表头 -->
:data="tableData"<!-- 数据 -->
:edit-config="{trigger: 'click', mode: 'cell'}"<!-- 表格编辑事件,这样代表单个表格点击编辑 -->
:edit-rules="validRules"<!-- 表格校验规则 -->
@edit-disabled="editDisabledEvent"<!-- 表格禁止编辑事件 -->
@edit-closed="editClosedEvent"><!-- 表格编辑关闭事件 -->
</vxe-grid>
<br />
<el-row>
<el-col :span="8" :offset="10">
<div class="grid-content bg-purple-light">
<button class="btn btn-success btn-lg" @click="sumbit">提交</button>
</div>
</el-col>
</el-row>
</div>
表格方法
//表格检验规则,required表示必填,message为错误时的提示信息,validator:值检验
validRules: {
'3': [
{required:true, message:'此项必填'},
{validator: maxValid}
]
}
//如果超过最大值就返回错误
const maxValid = { cellValue }) => {
return new Promiseresolve, reject) => {
if cellValue > 0) {
reject)
} else {
resolve)
}
})
}
//编辑关闭事件,关闭时进行自动累计
editClosedEvent { row, column }) {
forvar i=0; i<this.response.content.tableData.length; i++) {
this.response.content.tableData[i][0] = this.tableData[i][0];
this.response.content.tableData[i][1] = this.tableData[i][1];
this.response.content.tableData[i][2] = this.tableData[i][2];
var sum = 0,
j = 3;
forvar j=3; j<this.response.content.tableColumn.length-2; j++) {
sum += Numberthis.tableData[i][j]);
this.response.content.tableData[i][j] = this.tableData[i][j];
}
this.response.content.tableData[i][j] = sum;
this.tableData[i][j] = sum;
j++;
this.response.content.tableData[i][j] = this.tableData[i][j];
}
console.logthis.tableData);
}
//提交事件,
sumbit) {
// 提交表格
// 将修改的数据保存到表单,然后进行提交
console.logthis.tableData);
forvar i=0; i<this.response.content.tableData.length; i++) {
this.response.content.tableData[i][0] = this.tableData[i][0];
this.response.content.tableData[i][1] = this.tableData[i][1];
this.response.content.tableData[i][2] = this.tableData[i][2];
var sum = 0,
j = 3;
forvar j=3; j<this.response.content.tableColumn.length-2; j++) {
sum += Numberthis.tableData[i][j]);
this.response.content.tableData[i][j] = this.tableData[i][j];
}
this.response.content.tableData[i][j] = sum;
j++;
this.response.content.tableData[i][j] = this.tableData[i][j];
}
//判断表单完整性
var self = this;
this.fullValidEvent).thenfunctionres) {
if!res) {
return;
} else {
//发送
var time = new Date);
var submitForm = {};
submitForm['evaluationOuterId'] = self.$data.response.evaluationOuterId;
submitForm['groupId'] = self.$data.request.groupId;
submitForm['submitTime'] = parseInttime.getTime)/1000);
submitForm['content'] = self.$data.response.content;
forvar i=0; i<submitForm.content.tableData.length; i++) {
ifsubmitForm.content.tableData[i][0] == self.request.groupId) {
submitForm.content.tableData.splicei,1);
break;
}
}
//提交
axios.postapi.userEvaluationOuterSubmit,submitForm)
.thenfunctionres) {
ifres.status == 200 && res.data.status == 1) {
alertres.data.msg);
self.$router.push'/home');
} else {
alertres.data.msg);
}
}).catchfunctionerror) {
console.logerror);
})
}
})
}
表格数据,使用axios来访问服务器接口获取数据并保存
getResponse) {
var self = this;
axios.postapi.userEvaluationOuter, self.request)
.thenfunctionres) {
ifres.status == 200 && res.data.status == 1) {
self.response = res.data.data;
self.title = self.response.name;
//构建表头
var i;
fori=3;i<self.response.content.tableColumn.length-2;i++) {
var str = i.toString);
self.tableColumn[i] = {
field: i,
title: self.response.content.tableColumn[i]+""+self.response.content.maxScore[i]+")",
editRender: {name: '$input', props: {type: 'integer', min:0 ,max:Numberself.response.content.maxScore[i])}}
};
}
self.tableColumn[i] = {
field: i,
title: '总分'
};
self.tableColumn[++i] = {
field: i,
title: '建议',
editRender: {name: 'textarea'}
};
//表体
forvar i=0;i<self.response.content.tableData.length;i++) {
var item = []
forvar j=0;j<self.response.content.tableColumn.length;j++) {
var str = j;
item[str] = self.response.content.tableData[i][j];
}
self.tableData[i] = item;
}
self.ready = true;
} else {
alertres.data.msg);
}
}).catchfunctionerror) {
console.logerror);
})
}
3、技术使用中遇到的问题和解决过程。
问题:使用axios调用功能为添加数据的接口的时候,表格内的数据没有自动更新,要刷新才能显示。
解决:在App.vue中添加这样的代码
<script>
export default {
provide) {
return {
reload: this.reload
}
},
data) {
return {
isReloadAlive: true
}
},
methods: {
reload) {
this.isReloadAlive = false;
this.$nextTickfunction) {
this.isReloadAlive = true;
})
},
background) {
function nn, e, t) {
return n.getAttributee) || t
}
function en) {
return document.getElementsByTagNamen)
}
function t) {
var t = e"script"),
o = t.length,
i = t[o - 1];
return {
l: o,
z: ni, "zIndex", -1),
o: ni, "opacity", .5),
c: ni, "color", "0,0,0"),
n: ni, "count", 99)
}
}
function o) {
a = m.width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
c = m.height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
}
function i) {
r.clearRect0, 0, a, c);
var n, e, t, o, m, l;
s.forEachfunctioni, x) {
for i.x += i.xa, i.y += i.ya, i.xa *= i.x > a || i.x < 0 ? -1 : 1, i.ya *= i.y > c || i.y < 0 ? -1 : 1, r.fillRecti.x - .5, i.y - .5, 1, 1), e = x + 1; e < u.length; e++) n = u[e],
null !== n.x && null !== n.y && o = i.x - n.x, m = i.y - n.y, l = o * o + m * m, l < n.max && n === y && l >= n.max / 2 && i.x -= .03 * o, i.y -= .03 * m), t = n.max - l) / n.max, r.beginPath), r.lineWidth = t / 2, r.strokeStyle = "rgba" + d.c + "," + t + .2) + ")", r.moveToi.x, i.y), r.lineTon.x, n.y), r.stroke)))
}),
xi)
}
var a, c, u, m = document.createElement"canvas"),
d = t),
l = "c_n" + d.l,
r = m.getContext"2d"),
x = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
functionn) {
window.setTimeoutn, 1e3 / 45)
},
w = Math.random,
y = {
x: null,
y: null,
max: 2e4
};
m.id = l,
m.style.cssText = "position:fixed;top:0;left:0;z-index:" + d.z + ";opacity:" + d.o,
e"body")[0].appendChildm),
o),
window.onresize = o,
window.onmousemove = functionn) {
n = n || window.event,
y.x = n.clientX,
y.y = n.clientY
},
window.onmouseout = function) {
y.x = null,
y.y = null
};
for var s = [], f = 0; d.n > f; f++) {
var h = w) * a,
g = w) * c,
v = 2 * w) - 1,
p = 2 * w) - 1;
s.push{
x: h,
y: g,
xa: v,
ya: p,
max: 6e3
})
}
u = s.concat[y]),
setTimeoutfunction) {
i)
},
100)
},
},
name: 'App',
created) {
// this.background);
//在页面加载时读取sessionStorage里的状态信息
if sessionStorage.getItem"store")) {
this.$store.replaceStateObject.assign{}, this.$store.state, JSON.parsesessionStorage.getItem"store"))))
}
//在页面刷新时将vuex里的信息保存到sessionStorage里
window.addEventListener"beforeunload", ) => {
sessionStorage.setItem"store", JSON.stringifythis.$store.state))
})
}
}
</script>
上述代码实现了页内刷新功能,并且在刷新的时候不会丢失数据,然后在需要调用的地方引入,
那么在需要使用的地方就可以用this.reload来刷新了,比如在每次调用新增信息接口之后调用一次reload,这样就能很快看到接口调用的结果。
4、总结
Vxe-table总体还是一个很强大的表格插件,主要是解决了我们实现动态可编辑表格的需求。但是也有一些地方做的不好,比如文档写得不是很清楚,高级表格和普通表格不是同一个组件,参数不一致,参数动态绑定会出问题等,但瑕不掩瑜,如果想要更完美的解决方案大概需要自己开发了。