前面两节内容我们介绍了如何构建基于ASP.NET Web API的REST
风格的服务,虽然demo比较简单,,而且仅仅建了一张数据表,没有涉及较多多的数据表映射关系,但是对于初学者来说这样给入门提供了一个整体思路,先易后难,慢慢上手,毕竟知易行难。
今天这篇文章主要是在前面已经构建好Web API 服务的基础上,介绍下如何使用当下较火的Vue.js来解析Web API,编写一个小界面,完成从后端API到前端展示数据的一个整体demo。
什么是Vue.js
Vue.js 是用于构建交互式的 Web 界面的库。
Vue.js 提供了 MVVM 数据绑定和一个可组合的组件系统,具有简单、灵活的 API,让编写动态的UI界面变得轻松简单。
Vue.js 特点
- 简洁: HTML 模板 + JSON 数据,再创建一个 Vue 实例,就这么简单。
- 数据驱动: 自动追踪依赖的模板表达式和计算属性。
- 组件化: 用解耦、可复用的组件来构造界面。
- 轻量: ~24kb min+gzip,无依赖。
- 快速: 精确有效的异步批量 DOM 更新。
- 模块友好: 通过 NPM 或 Bower 安装,无缝融入你的工作流。
Vue.js 安装
这里我们只介绍使用<script>
标签引入,NPM
安装和Bower
安装小伙伴们可以参考网上的教程。
1.引用方法一:
直接下载并用 <script>
标签引入,Vue 会被注册为一个全局变量。
Vue.js 官网下载地址:http://vuejs.org/guide/installation.html
在我们的demo中引用如下:1
<script src="~/Scripts/vue.js"></script>
2.引用方法二:
使用其静态资源 CDN 库,在我们的demo中引用如下:1
<script src="http://cdnjs.cloudflare.com/ajax/libs/vue/1.0.7/vue.min.js"></script>
什么是vue-resource
vue-resource是Vue.js的一款插件,它可以通过XMLHttpRequest或JSONP发起请求并处理响应。
vue-resource特点
vue-resource插件具有以下特点:
- 体积小:vue-resource非常小巧,在压缩以后只有大约12KB,服务端启用gzip压缩后只有4.5KB大小,这远比jQuery的体积要小得多。
- 支持主流的浏览器:和Vue.js一样,vue-resource除了不支持IE 9以下的浏览器,其他主流的浏览器都支持。
- 支持拦截器:拦截器是全局的,拦截器可以在请求发送前和发送请求后做一些处理。
拦截器在一些场景下会非常有用,比如请求发送前在headers中设置access_token,或者在请求失败时,提供共通的处理方式。
引入vue-resource
同Vue.js的引用一样,有两种引入方法:
1.引用方法一:
在我们的demo中引用如下:1
<script src="~/Scripts/vue-resource.js"></script>
2.引用方法二:
使用其静态资源 CDN 库,在我们的demo中引用如下:1
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-resource/0.1.17/vue-resource.js"></script>
基本语法
引入vue-resource后,可以基于全局的Vue对象使用http,也可以基于某个Vue实例使用http。1
2
3
4
5
6
7// 基于全局Vue对象使用http
Vue.http.get('/someUrl', [options]).then(successCallback, errorCallback);
Vue.http.post('/someUrl', [body], [options]).then(successCallback, errorCallback);
// 在一个Vue实例内使用$http
this.$http.get('/someUrl', [options]).then(successCallback, errorCallback);
this.$http.post('/someUrl', [body], [options]).then(successCallback, errorCallback);
上述的then
方法的回调函数也有两种写法,第一种是传统的函数写法,第二种是更为简洁的ES 6的Lambda写法:1
2
3
4
5
6
7
8
9
10
11
12
13
14// 传统写法
this.$http.get('/someUrl', [options]).then(function(response){
// 响应成功回调
}, function(response){
// 响应错误回调
});
// Lambda写法
this.$http.get('/someUrl', [options]).then((response) => {
// 响应成功回调
}, (response) => {
// 响应错误回调
});
在本demo中使用第二种Lambda写法总是报语法错误,所以仍然采用的是传统写法
下面开始我们本demo前端界面构建的具体介绍。最终完成的效果如下图所示:
Views结构
在WebAPIDemo
项目的Views
文件夹中,我们可以看到有Home
文件夹、Shared
文件夹、_ViewStart.cshtml
文件,其中,Home
文件夹放置网站主页文件,Shared
文件夹放置模板文件,_ViewStart.cshtml
进行初始化。
在demo中使用的前端框架是BootStrap
,这里我们将使用Shared
文件夹下的模板文件,因此我们在Home
文件夹下的html代码只需要写body
部分;当然了,如果你不想使用模板文件,需要引入如下代码:1
2
3@{
Layout = null;
}
引入js文件
我们本次demo做一个单页界面作为主页,因此需要在Home文件下的Index.cshtml
进行代码的编写,现在我们把Index.cshtml
下的代码清空。
首先引入js文件,这里我用CDN库的方式引入。需要注意的是引用版本问题,我发现这是一个大坑啊,引用版本不一样导致编译直接出错,所以大家可以采用下面的应用方法:1
2<script src="http://cdnjs.cloudflare.com/ajax/libs/vue/1.0.7/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-resource/0.1.17/vue-resource.js"></script>
编写html代码
在demo中我们实现的是取回Web API返回的值以表格的方式进行展示,同时能够进行添加和删除操作,具体实现的是StudentController.cs
中的get
、post
、delete
方法。代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55<div class="container">
<div class="col-md-6 col-md-offset-3">
<h1>Vue.js demo</h1>
<div id="app">
<table class="table table-hover" v-cloak>
<thead>
<tr>
<th class="text-center">姓名</th>
<th class="text-center">学号</th>
<th class="text-center">班级</th>
<th class="text-center">电话</th>
<th class="text-center">操作</th>
</tr>
</thead>
<tbody>
<tr v-for="student in students ">
<td class="text-center">{{student.Name}}</td>
<td class="text-center">{{student.StuID}}</td>
<td class="text-center">{{student.Class}}</td>
<td class="text-center">{{student.Phone}}</td>
<td class="text-center">
<button type="button" class="btn btn-danger" v-on:click="deleteStudent(student)">删除</button>
</td>
</tr>
</tbody>
</table>
<legend>添加学生信息:{{ stu.Name }}</legend>
<div v-show="stu.ID" class="form-group">
<label>ID</label>
<input type="text" v-model="stu.ID" disabled="disabled" />
</div>
<div class="form-group">
<label for="">姓名</label>
<input type="text" class="form-control" v-model="stu.Name">
</div>
<div class="form-group">
<label for="">学号</label>
<input type="text" class="form-control" v-model="stu.StuID">
</div>
<div class="form-group">
<label for="">班级</label>
<input type="text" class="form-control" v-model="stu.Class">
</div>
<div class="form-group">
<label for="">电话</label>
<input type="text" class="form-control" v-model="stu.Phone">
</div>
<button class="btn btn-primary btn-block" v-on:click="createStudent(student)">添加</button>
</div>
</div>
</div>
编写js代码
vue-resource的请求API是按照REST风格设计的,它提供了7种请求API:
- get(url, [options])
- head(url, [options])
- delete(url, [options])
- jsonp(url, [options])
- post(url, [body], [options])
- put(url, [body], [options])
- patch(url, [body], [options])
除了jsonp以外,另外6种的API名称是标准的HTTP方法。当服务端使用REST API时,客户端的编码风格和服务端的编码风格近乎一致,这可以减少前端和后端开发人员的沟通成本。
本demojs代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49<script>
Vue.http.options.emulateJSON = true;
var demo = new Vue({
el: '#app',
data: {
student: [{
name: 'ID',
isKey: true
}, {
name: 'Name'
}, {
name: 'StuID'
}, {
name: 'Class'
}, {
name: 'Phone'
}],
students: [],
apiUrl: 'http://localhost:7874/api/students',
stu: {}
},
ready: function() {
this.getStudents()
},
methods: {
getStudents: function () {
this.$http.get(this.apiUrl, function (data) {
this.$set('students', data);
})
},
createStudent: function() {
var vm = this
vm.$http.post(vm.apiUrl, vm.stu)
.then(function(response) {
vm.$set('stu', {})
vm.getStudents()
})
},
deleteStudent: function(student){
var vm = this
vm.$http.delete(this.apiUrl + '/' + student.ID)
.then(function(response) {
vm.getStudents()
})
}
}
})
</script>
ok,至此代码已经写完了,运行查看一下效果,可以实现我们所需的功能。
双向数据绑定
最后我们简单说一下数据绑定,在上面的代码中,有如下代码:1
2
3
4
5
6
7
8
9<legend>添加学生信息:{{ stu.Name }}</legend>
<div v-show="stu.ID" class="form-group">
<label>ID</label>
<input type="text" v-model="stu.ID" disabled="disabled" />
</div>
<div class="form-group">
<label for="">姓名</label>
<input type="text" class="form-control" v-model="stu.Name">
</div>
使用v-model这个指令完成中间的底层逻辑,实现绑定的效果。改变其中的任何一层,另外一层都会改变。
以上实例中 会根据输入框 input(标签为“姓名”) 的改变而改变(v-model=”stu.Name”)。
ok,本入门系列暂且告一段落,大家多多参考网上大牛的博客,只有自己趟过的坑才会牢牢记住,知道自己如何避免踩到同样的坑。
ASP.NET Web API 入门实战系列:
本demo源码已上传到Github:WebAPIDemo-Vuejs