python工业互联网应用实战9—使用Vue.js
本章简要的说明如何通过对监控页面的简单重构,快速的使用上vue.js这个当红的界面开发javascript组件。vue.js有诸多优势,笔者使用中感触最多的就是数据的双向绑定!通过组件双向绑定,当ajax刷新后台数据了,页面会自动重新渲染刷新数据;UI input控件value值被人机交互更新了,数据也会自动的同步到model,这样省去了早些年编程的get一遍赋值操作,保存时又一遍赋值操作。这个双向赋值一直是笔者从业以来觉得需要除去的“面条代码”,尤其是model属性值非常多的时候,变更经常让我们在某个环节少了某个属性的赋值操作引入bug,直到遇到vue组件...
以下面的代码就是早期的前端jquery脚本代码,提交数据的时候赋值获取空框的值,这个contractBill涉及一个大表,字段非常的多,光赋值代码就可以刷屏了。
...
if (gContractBill == null) {if (gEnableLargeNumberOfCustomers) {
contractBill.CustomerId = $('#txtCustomer').attr("data-WarehouseCustomerId");
contractBill.CustomerName = $('#txtCustomer').attr("data-CustomerName");
contractBill.CustomerGradeId = $('#txtCustomer').attr("data-CustomerGradeId");
contractBill.PublicCustomerId = $('#txtCustomer').attr("data-PublicCustomerId");
contractBill.PinYin = $('#txtCustomer').attr("data-PinYin");
contractBill.CustomerStationId = $('#txtCustomer').attr("data-WarehouseCustomerStationId");
contractBill.StationName = $('#txtCustomer').attr("data-StationName");
} else {
contractBill.CustomerId = $('#selCustomerName').find("option:selected").attr("data-CustomerId");
contractBill.CustomerName = $('#selCustomerName').find("option:selected").attr("data-CustomerName");
contractBill.CustomerGradeId = $('#selCustomerName').find("option:selected").attr("data-CustomerGradeId");
contractBill.PublicCustomerId = $('#selCustomerName').find("option:selected").attr("data-PublicCustomerId");
contractBill.PinYin = $('#selCustomerName').find("option:selected").attr("data-PinYin");
contractBill.CustomerStationId = $('#selCustomerName').val();
contractBill.StationName = $('#selCustomerName').find('option:selected').text();
}
contractBill.DepartmentId = gLogonData.TeamBranchs[0].BranchId;
contractBill.DepartmentName = gLogonData.TeamBranchs[0].BranchName;
...
上面这个代码只是提交的时候赋值操作片段的,ajax get过来刷新组件显示还得赋值一遍!
1.1. JQuery和Vue
现在我们改造监控界面来快速的演示使用vue.js。前章节的例子我们通过ajax刷新界面数据是通过jquery操作div id来实现的更新显示值,这个小节我们将重构这个ui端代码,采用vue来小试一下数据的双向绑定,实现数据的自动刷新。从而对比两种方式ui编码的不同,vue是笔者使用过的非常值得赞叹的组件之一。
根据vue的规则,我们把原来的显示值修改成{{overheadFlow}}数据变量,由于“{{}}”与django的模板“{{}}”冲突,这里我们把vue的修改成“[[]]”才行。vue的数据双向绑定编码的时候我们只关注model的属性值即可,界面的输入控件值发生时,不需要的提交的时候重新把控件的值再重新赋值给model。当我们的表单修改的model属性太多的时候,这个功能非常非常实用。
<!DOCTYPE html><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>Tank 4C9</title>
<link href="https://cdn.bootcss.com/twitter-bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<!--<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.slim.min.js"></script>-->
<script src="https://cdn.bootcss.com/twitter-bootstrap/4.4.1/js/bootstrap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style type="text/css">
.bg {
background: url(../../static/img/tank4C9-1.png) no-repeat left;
background-size: contain;
}
</style>
</head>
<body >
<div id="content-main" class="container-fluid bg" style="height:455px;background:url(../../static/img/tank4C9-1.png) no-repeat left;background-size:contain;">
<div class="row"> </div>
<div class="row"> </div>
<div class="row">
<div class="col-sm"></div>
<div class="col-sm" ><span class="text-warning" id="OverheadFlow">[[model.OverheadFlow]]</span><span> mm/sΛ2</span></div>
<div class="col-sm"></div>
</div>
<div class="row"> </div>
<div class="row"> </div>
<div class="row"> </div>
<div class="row">
<div class="col-sm"></div>
<div class="col-sm-2"> <span class="text-success" id="Power">[[model.Power]]</span><span> kWh</span></div>
<div class="col-sm-9"></div>
</div>
<div class="row"> </div>
<div class="row"> </div>
<div class="row"> </div>
<div class="row"> </div>
<div class="row"> </div>
<div class="row"> </div>
<div class="row"> </div>
<div class="row"> </div>
<div class="row"> </div>
<div class="row"> </div>
<div class="row">
<div class="col-sm-5"></div>
<div class="col-sm-2"><span class="text-danger" id="ButtomsFlow">[[model.ButtomsFlow]]</span><span> mm/sΛ2</span></div>
<div class="col-sm-5"></div>
</div>
</div>
<script>
////JQuery 代码入口
// $(document).ready(function(){
// setInterval("getData()",1000);
// });
// function getData() {
// //模拟异步从后台获得值
// $.ajax({
// url: "/getTank4C9Data/", success: function (result) {
// data = JSON.parse(result);
// $("#OverheadFlow").html(data.OverheadFlow);
// $("#ButtomsFlow").html(data.ButtomsFlow);
// $("#Power").html(data.Power);
// }});
// }
var vm= new Vue({
el: '#content-main',
data: {
overheadFlow: 10,
power: 20,
buttomsFlow: 30,
timer:'',
},
delimiters: ['[[', ']]'], //①
mounted() {
this.timer = setInterval(this.getData, 1000);
},
// 在 `methods` 对象中定义方法
methods: {
getData: function (event) {
_this = this
$.ajax({
url: "/getTank4C9Data/", success: function (result) {
data = JSON.parse(result);
//②
_this.overheadFlow = data.OverheadFlow
_this.buttomsFlow = data.ButtomsFlow
_this.power = data.Power
}
});
}
},
beforeDestroy() {
clearInterval(this.timer);
}
});</script>
</body>
</html>
标注①:注意这里修改与django冲突的模板标识符号。
标注②:ajax 调用返回数据后,只更新data里面定义的属性即可。
现在运行这个页面,在功能不变的情况下,整个前端页面的渲染就使用上了vue.js。对比上面两段代码,你发现两者的差别不是很大,只是vue有一个data用来定义需要刷新的数据项,然后在html定义好对应的模板变量[[overheadFlow]]等,后面数据的刷新就交由vue.js来执行了,标注①的代码ajax 调用返回数据后,只更新data里面定义的属性即可,监控页面的数据就自动的刷新了,无须关注html控件。
1.2. 进一步重构代码
通过上述小节,我们实现了原有的实时刷新数据功能,现在我们功能不变的情况下,进一步优化代码结构,在vue的data里直接定义一个标准返回的数据结构。
var vm= new Vue({el: '#content-main',
data: { //①
model: {
OverheadFlow: 10,
Power: 20,
ButtomsFlow: 30,
},
timer: '',
},
delimiters: ['[[', ']]'],
mounted() {
this.timer = setInterval(this.getData, 1000);
},
// 在 `methods` 对象中定义方法
methods: {
getData: function (event) {
_this = this
$.ajax({
url: "/getTank4C9Data/", success: function (result) {
//②
_this.model = JSON.parse(result);
}
});
}
},
beforeDestroy() {
clearInterval(this.timer);
}
});
①:定义与ajax获取的model一样的数据结构格式
②:优化成直接更新vue里的model 对象,这样代码就显得更加简单了!
同时记得把模板里的[[model.Power]] 变量改成model的属性,在功能不变代的前提下,这个重构让代码更简洁了。
运行结果如下图:
1.3. 小结
从上面的代码可以看出,完成data属性与组件的绑定后后面编码无须再关注控件id或者class,所有的代码只关注data属性值即可,这一分层逻辑带了极大的好处,编写业务的时候把精力集中关注业务即可,不用再担心是否哪儿少了一个赋值操作语句,页面的布局与css等则可以放到另外的时间去完成。Vue.js前端页面的处理模式给企业开发方面带来了实质性的“一大步”。
以上是 python工业互联网应用实战9—使用Vue.js 的全部内容, 来源链接: utcz.com/z/379769.html