zoukankan      html  css  js  c++  java
  • 个人技术总结——Vxe-table

    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 Promise((resolve, reject) => {
    		if (cellValue > 0) {
    			reject()
    		} else {
    			resolve()
    		}
    	})
    }
    
    //编辑关闭事件,关闭时进行自动累计
    editClosedEvent ({ row, column }) {
    	for(var 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;
    		for(var j=3; j<this.response.content.tableColumn.length-2; j++) {
    			sum += Number(this.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.log(this.tableData);
    }
    
    //提交事件,
    sumbit() {
    	// 提交表格
    	// 将修改的数据保存到表单,然后进行提交
    	console.log(this.tableData);
    	for(var 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;
    		for(var j=3; j<this.response.content.tableColumn.length-2; j++) {
    			sum += Number(this.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().then(function(res) {
    		if(!res) {
    			return;
    		} else {
    			//发送
    			var time = new Date();
    			var submitForm = {};
    			submitForm['evaluationOuterId'] = self.$data.response.evaluationOuterId;
    			submitForm['groupId'] = self.$data.request.groupId;
    			submitForm['submitTime'] = parseInt(time.getTime()/1000);
    			submitForm['content'] = self.$data.response.content;
    			
    			for(var i=0; i<submitForm.content.tableData.length; i++) {
    				if(submitForm.content.tableData[i][0] == self.request.groupId) {
    					submitForm.content.tableData.splice(i,1);
    					break;
    				}
    			}
    			
    			//提交
    			axios.post(api.userEvaluationOuterSubmit,submitForm)
    			.then(function(res) {
    				if(res.status == 200 && res.data.status == 1) {
    					alert(res.data.msg);
    					self.$router.push('/home');
    				} else {
    					alert(res.data.msg);
    				}
    			}).catch(function(error) {
    				console.log(error);
    			})
    		}
    	})
    }
    

    表格数据,使用axios来访问服务器接口获取数据并保存

    getResponse() {
    	var self = this;
    	axios.post(api.userEvaluationOuter, self.request)
    	.then(function(res) {
    		if(res.status == 200 && res.data.status == 1) {
    			self.response = res.data.data;
    			self.title = self.response.name;
    			//构建表头
    			var i;
    			for(i=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:Number(self.response.content.maxScore[i])}}
    				};
    			}
    			self.tableColumn[i] = {
    				field: i,
    				title: '总分'
    			};
    			self.tableColumn[++i] = {
    				field: i,
    				title: '建议',
    				editRender: {name: 'textarea'}
    			};
    			//表体
    			for(var i=0;i<self.response.content.tableData.length;i++) {
    				var item = []
    				for(var 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 {
    			alert(res.data.msg);
    		}
    	}).catch(function(error) {
    		console.log(error);
    	})
    }
    

    3、技术使用中遇到的问题和解决过程。

    问题:使用axios调用功能为添加数据的接口的时候,表格内的数据没有自动更新,要刷新才能显示。
    解决:在App.vue中添加这样的代码

    <script>
    	export default {
    		provide() {
    			return {
    				reload: this.reload
    			}
    		},
    		data() {
    			return {
    				isReloadAlive: true
    			}
    		},
    		methods: {
    			reload() {
    				this.isReloadAlive = false;
    				this.$nextTick(function() {
    					this.isReloadAlive = true;
    				})
    			},
    			background() {
    			    function n(n, e, t) {
    			        return n.getAttribute(e) || t
    			    }
    			    function e(n) {
    			        return document.getElementsByTagName(n)
    			    }
    			    function t() {
    			        var t = e("script"),
    			        o = t.length,
    			        i = t[o - 1];
    			        return {
    			            l: o,
    			            z: n(i, "zIndex", -1),
    			            o: n(i, "opacity", .5),
    			            c: n(i, "color", "0,0,0"),
    			            n: n(i, "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.clearRect(0, 0, a, c);
    			        var n, e, t, o, m, l;
    			        s.forEach(function(i, 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.fillRect(i.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.moveTo(i.x, i.y), r.lineTo(n.x, n.y), r.stroke()))
    			        }),
    			        x(i)
    			    }
    			    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 ||
    			    function(n) {
    			        window.setTimeout(n, 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].appendChild(m),
    			    o(),
    			    window.onresize = o,
    			    window.onmousemove = function(n) {
    			        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]),
    			    setTimeout(function() {
    			        i()
    			    },
    			    100)
    			},
    			
    		},
    		name: 'App',
    		created() {
    			// this.background();
    			//在页面加载时读取sessionStorage里的状态信息
    			if (sessionStorage.getItem("store")) {
    				this.$store.replaceState(Object.assign({}, this.$store.state, JSON.parse(sessionStorage.getItem("store"))))
    			}
    
    			//在页面刷新时将vuex里的信息保存到sessionStorage里
    			window.addEventListener("beforeunload", () => {
    				sessionStorage.setItem("store", JSON.stringify(this.$store.state))
    			})
    		}
    	}
    </script>
    

    上述代码实现了页内刷新功能,并且在刷新的时候不会丢失数据,然后在需要调用的地方引入,

    那么在需要使用的地方就可以用this.reload来刷新了,比如在每次调用新增信息接口之后调用一次reload,这样就能很快看到接口调用的结果。

    4、总结

    Vxe-table总体还是一个很强大的表格插件,主要是解决了我们实现动态可编辑表格的需求。但是也有一些地方做的不好,比如文档写得不是很清楚,高级表格和普通表格不是同一个组件,参数不一致,参数动态绑定会出问题等,但瑕不掩瑜,如果想要更完美的解决方案大概需要自己开发了。

    5、参考文献

    Vxe-table官方文档

  • 相关阅读:
    NHibernate 使用点滴
    看了二十四画生的文章才发现ASP.NET Portal Starter Kit中调整顺序的一个Bug
    闲话静态构造函数
    ASP.NET Portal starter Kit 之页面配置文件
    VB智能中文提示的一个小工具 VBCommenter 1.2.5
    61条面向对象设计的经验原则
    asp.net Portal Starter kit改造Portal的Html文本编辑器
    Wrox出版社的 Professional DotNetNuke Asp.NET Portals [E文版] 电子书的下载地址
    asp.net Datagrid 资源
    C#与vb.net的区别
  • 原文地址:https://www.cnblogs.com/cazenove/p/13178278.html
Copyright © 2011-2022 走看看