原有项目运用vue的痛点
前端手艺的生长可谓一日千里,更有甚者,在deno开源项目的issue中发“求不要更新了,老子学不动了”,这消息传遍中国的手艺圈子,有人说这是中国人的羞辱。这里我就不批评优劣。但可见,前端生长的速率异常惊人。
但“存期近合理”,黑格尔的这句话,在手艺领域越发是。能够生长的手艺,肯定更人们带来方便。扩展处理题目的局限,或者是进步处理需求的速率等等。
但是关于背景职员,面临遗留下来的背景体系,并没有完整前后端星散,也有公司只要背景职员,前后端都干。那末题目来了,上述这类情况下怎样进步效力呢。引入Angular、React、Vue是能处理效力题目,得益于其MVVM手艺将视图UI和营业逻辑离开等四大特征:
- 低耦合。视图(View)能够自力于Model变化和修正,一个ViewModel能够绑定到差别的”View”上,当View变化的时刻Model能够稳定,当Model变化的时刻View也能够稳定。
- 可重用性。你能够把一些视图逻辑放在一个ViewModel内里,让许多view重用这段视图逻辑。
- 自力开辟。开辟职员能够专注于营业逻辑和数据的开辟(ViewModel)。
- 可测试。界面夙来是比较难于测试的,而如今测试能够针对ViewModel来写。
上述特征是否是笼统,前端职员都以为前端手艺生长之快,后端职员就更难打仗和体味。vue官网的例子更是以webpack等模块化例子来解说,如许以来,假如想运用vue的优点罢了,还要去相识webpack、AMD等等,这让后端职员再三地望而生畏。
除了手艺栈的限定,项目时候也是个门坎,虽然我以为前端许多头脑都是源自于后端的头脑,如模块化,mvc,构建手艺等,但学起来照样要时候呢。老板并不会给时候开辟职员去把全部前端推倒了重干。推倒重干也不切实际,一本钱高,二风险大(如能不能完成,或能不能赶在市场时机眼前完成)。所以渐进地转变是比较稳妥的(保守主义)。
所以这里分享下我在老项目疾速运用vue的履历。
vue履历
在原有有项目的html页面里,引入vue的依靠
<!-- Vue.js v2.5.16 -->
<script src="/js/vue/vue.min.js"></script>
<!-- vue-resource v1.5.1 用于ajax要求-->
<script src="/js/vue/vue-resource.min.js"></script>
本例子是一个增加用户表单的提交,就只要运用几个属性 v-model,v-for和v-on:click,以及{{}}占位符
此时html代码只需修正以下(专注于展现):
<div class="form-horizontal" method="post" id="userFrom">
<div class="form-group">
<input type="text" class="form-control" id="name" placeholder="请输入用户账号" v-model="name" >
</div>
<div class="form-group">
<input type="password" class="form-control" id="name" placeholder="请输入用户暗码" v-model="name" >
</div>
<div class="form-group">
<button type="button" class="btn btn-success" data-toggle="modal" data-target="#myModal">挑选角色</button>
<table class="table table-hover" >
<thead>
<tr>
<th>操纵</th>
<th>角色ID</th>
<th>角色称号</th>
</tr>
</thead>
<tbody>
<tr v-for="(item,index) in nodeList">
<td>
<button type="button" class="btn btn-danger" v-on:click="remove($event,index)">移除</button>
</td>
<th scope="row">{{ item.id }}</th>
<td>{{ item.name }}</td>
</tr>
</tbody>
</table>
</div>
<div class="form-group">
<textarea placeholder="请输入备注" name="remark" id="remark" v-model="remark"></textarea>
</div>
<div class="form-group">
<div class="col-xs-2">
<button class="btn btn-primary btn-block btn-flat" v-on:click="createUser">增加</button>
</div>
</div>
</div>
<!-- 弹出框,挑选角色,上面的挑选角色按钮则弹出以下对话框,这个是boostra手艺的领域,但不影响vue的运用 -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">
×
</button>
<h4 class="modal-title" id="myModalLabel">
挑选角色
</h4>
</div>
<div class="modal-body">
<table class="table table-hover" id="toChooseTable">
<thead>
<tr>
<th>操纵</th>
<th>角色ID</th>
<th>角色称号</th>
</tr>
</thead>
<tbody>
<tr v-for="(item,index) in toChooseList">
<td>
<button type="button" class="btn btn-danger" v-on:click="choose($event,index)">挑选</button>
</td>
<th scope="row">{{ item.id }}</th>
<td>{{ item.name }}</td>
</tr>
</tbody>
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">封闭
</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal -->
</div>
script代码修正(专注于数据及其操纵)
<script >
//提交表单中的数据及操纵
var userFrom = new Vue({
el: '#userFrom',
data: {
name:'',
password:'',
remark:'',
roleList: [],
apiUrl: '/user/add'
},
// 在 `methods` 对象中定义要领
methods: {
remove: function (event,index) {
//移除角色
//1.将未被挑选的角色数据放回弹出框内
pushToChooseList(this.roleList[index]);
//2.在已挑选的角色table里移除这个角色数据
this.roleList.splice(index,1);
},
createUser: function() {
var params = {
name:this.name,
password:this.password,
remark:this.remark,
roleList:[]
};
for(var i=0;i<this.roleList.length;i++){
var role={};
role.id = this.roleList[i].id;
role.name = this.roleList[i].name;
params.roleList.push(node);
}
this.$http.post(this.apiUrl,JSON.stringify(params),{
emulateJSON:false
}).then(function(response){
// response.data中猎取ResponseData实体
console.log(response);
},function(response){
// 发作毛病
console.log(response);
});
}
}
})
//弹出框数据及操纵
var toChooseTable = new Vue({
el: '#toChooseTable',
data: {
toChooseList: [
],
apiUrl: '/role/list'
},
// 在 `methods` 对象中定义要领
methods: {
loadData: function() {
//加载角色数据
this.$http.post(this.apiUrl, {}).then(function (response) {
var result = response.data;
for (var i = 0; i < result.data.length; i++) {
var role = {};
role.id = result.data[i].id;
role.name = result.data[i].name;
toChooseTable.toChooseList.push(node);
}
}, function () {
console.log('failed');
});
},
choose: function (event,index)
//挑选角色
//1.将挑选的角色数据放入被选中的table里
pushChoosedList(this.toChooseList[index]);
//2.移除已被挑选的弹出框的角色数据
this.toChooseList.splice(index,1);
}
}
})
//加载角色数据
toChooseTable.loadData();
function pushChoosedList(data) {
for(j = 0,len=userForm.roleList.length; j < len; j++) {
if(userForm.roleList[j].id==data.id){
return;
}
}
userForm.roleList.push(data);
}
function pushToChooseList(data) {
for(j = 0,len=toChooseTable.toChooseList.length; j < len; j++) {
if(toChooseTable.toChooseList[j].id==data.id){
return;
}
}
toChooseTable.toChooseList.push(data);
}
</script>
上述例子很好的展现视图层和数据层的星散,视图和数据层都是零丁离开写的,不知道你能不能从中体味到效力的进步。之前这类弹出框选中数据,在table列表中展现,但是要写很多js代码,需手工建立tr标签,然后再append进table标签等,还要遍历定位标签,横竖写个页面都老半天。有了vue,这效力几乎大大的进步了。
element-ui履历
上述例子中,我们体味到视图层和数据层的星散,但还不是很明白模块化复用,以下就举个模块化复用优点的例子,就是运用element-ui的列表及分页。
引入element-ui
在上述vue基础上,引入:
<!-- 引入款式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- 引入组件库_element-ui@2.4.4@element-ui,官网不供应直接下载,需用cnpm i element-ui -S下载,然后复制lib目次 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
只需要引入element-ui的table组件和分页组件,即可到达复用
修正html代码:
<div class="ibox-content" id="content">
<!-- table组件 参考:http://element-cn.eleme.io/#/zh-CN/component/table-->
<el-table
:data="tableData"
style="width: 100%">
<el-table-column
label="日期"
width="180">
<template slot-scope="scope">
<i class="el-icon-time"></i>
<span style="margin-left: 10px">{{ scope.row.date }}</span>
</template>
</el-table-column>
<el-table-column
label="姓名"
width="180">
<template slot-scope="scope">
<el-popover trigger="hover" placement="top">
<p>姓名: {{ scope.row.name }}</p>
<p>住址: {{ scope.row.address }}</p>
<div slot="reference" class="name-wrapper">
<el-tag size="medium">{{ scope.row.name }}</el-tag>
</div>
</el-popover>
</template>
</el-table-column>
<el-table-column label="操纵">
<template slot-scope="scope">
<el-button
size="mini"
@click="handleEdit(scope.$index, scope.row)">编辑</el-button>
<el-button
size="mini"
type="danger"
@click="handleDelete(scope.$index, scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页组件-->
<div align="center">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="page"
:page-sizes="[10, 20, 30, 40]"
:page-size="rows"
layout="total, sizes, prev, pager, next, jumper"
:total="totalRecord">
</el-pagination>
</div>
</div>
修正script代码
<script >
/*<![CDATA[*/
var content = new Vue({
el: '#content',
data: {
tableData: [{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
}],
url:'/user/list',
//搜刮前提
criteria: '',
//下拉菜单选项
select: '',
//默许每页数据量
rows: 10,
//当前页码
page: 1,
//查询的页码
start: 1,
//默许数据总数
totalRecord: 1000
},
// 在 `methods` 对象中定义要领
methods: {
loadData: function(criteria, pageNum, pageSize){
this.$http.post(this.url,{criteria:criteria, page:pageNum, rows:pageSize},{emulateJSON:true}).then(function(res){
var page = res.data;
this.tableData = page.data;
this.totalRecord = page.totalRecord;
},function(){
console.log('failed');
});
},
handleEdit: function (index, row) {
console.log(index, row);
},
handleDelete: function (index, row) {
console.log(index, row);
},
//每页显现数据量变动
handleSizeChange: function(val) {
this.rows = val;
this.loadData(this.criteria, this.page, this.rows);
},
//页码变动
handleCurrentChange: function(val) {
this.page = val;
this.loadData(this.criteria, this.page, this.rows);
}
}
})
//加载数据
content.loadData(content.criteria, content.page, content.rows);
/*]]>*/
</script>
虽然没有运用webpack更完全的模块化。但上述的列子,也够给老项目带来复用的效力提拔,背景职员不必花时候去调款式。