Preface:
由于最近在研究前端相关的技术,作为前端非常优秀的框架Vue,个人在学习的过程中遇到一些问题,网上相关资料有限,所以在这这里总结一下个人使用Vue的一点经验,以便后来者借鉴!
官方文档:Vue.js
使用Vue在ASP.NET MVC中进行前后端交互
在阅读下面的文章之前你需要先了解一下Vue官方推荐的前后端交互的插件:
1.resource(官方在2.0版本之后取消了对此插件的维护)
2.axios
注:这里使用的都是异步的插件,因为这样才会在你的项目中具有使用意义,当然你也可以用其它的js库,如jQuery、Fetch等等...
Instance:
Controller
1 using Demo.Models;
2 using System;
3 using System.Collections.Generic;
4 using System.Linq;
5 using System.Web;
6 using System.Web.Mvc;
7
8 namespace Demo.Controllers
9 {
10 //[RoutePrefix("api/Goods")]
11 public class GoodsController : Controller
12 {
13 List<GoodsEntity> goosdList = new List<GoodsEntity>
14 {
15 new GoodsEntity(){ ID=001,Name="水",Type=1,Price=3},
16 new GoodsEntity(){ ID=002,Name="牛奶",Type=1,Price=10},
17 new GoodsEntity(){ ID=003,Name="面包",Type=2,Price=15}
18 };
19
20 // GET: Goods
21 public ActionResult Index()
22 {
23 return View();
24 }
25
26 public ActionResult Check()
27 {
28 return View();
29 }
30
31 [HttpGet]
32 public JsonResult GetGoodsType()
33 {
34 List<int> goodsType = new List<int>();
35 foreach (var item in goosdList)
36 {
37 if (!goodsType.Contains(item.Type))
38 {
39 goodsType.Add(item.Type);
40 }
41 }
42 return Json(goodsType, JsonRequestBehavior.AllowGet);
43 }
44
45 [HttpGet]
46 public JsonResult GetAllGoods()
47 {
48 return Json(goosdList, JsonRequestBehavior.AllowGet);
49 }
50
51 [HttpPost]
52 public JsonResult GetGoods(int id)
53 {
54 var entity = goosdList.Where(g => g.ID == id).FirstOrDefault();
55 if (entity != null)
56 {
57 return Json(new ReturnJsonInfo(500, "success!", entity));
58 }
59 return Json(new ReturnJsonInfo(400, "error!", null));
60 }
61
62 [HttpPost]
63 public JsonResult UpdateGoods(GoodsEntity entity)
64 {
65 if (entity!=null)
66 {
67 var goodsEntiy = goosdList.FirstOrDefault(g => g.ID == entity.ID);
68 if (goodsEntiy!=null)
69 {
70 goodsEntiy = entity;
71 return Json(new ReturnJsonInfo(500, "success!", goosdList));
72 }
73 goosdList.Add(entity);
74 return Json(new ReturnJsonInfo(500, "success!", goosdList));
75 }
76 return Json(new ReturnJsonInfo(400, "error!",null));
77 }
78
79 [HttpPost]
80 public JsonResult DelectGoods(int id)
81 {
82 var entity = goosdList.Where(g => g.ID == id).FirstOrDefault();
83 if (entity != null)
84 {
85 goosdList.Remove(entity);
86 return Json(new ReturnJsonInfo(500, "success!", goosdList));
87 }
88 return Json(new ReturnJsonInfo(400, "error!",null));
89 }
90
91 }
92 }
在上面的控制器中加载了一些示例数据,并且都是以json的格式返回前端,这样前端就可以直接使用这些数据。
注:控制器返回至前端的json中,上面使用 “ReturnJsonInfo” 对象序列化进行返回, “ReturnJsonInfo” 代码如下。
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Web;
5
6 namespace Demo.Models
7 {
8 public class ReturnJsonInfo
9 {
10 public int Code { get; set; }
11 public string Message { get; set; }
12 public object Entity { get; set; }
13 public ReturnJsonInfo(int code, string message,object obj)
14 {
15 this.Code = code;
16 this.Message = message;
17 this.Entity = obj;
18 }
19 }
20 }
View
1.前端采用resource插件
1 @{
2 ViewBag.Title = "Goods IndexPage";
3 }
4 <script type="text/javascript" src="~/Resources/Scripts/vue.js"></script>
5 <script type="text/javascript" src="~/Resources/Scripts/vue-resource.js"></script>
6 <h2>Index</h2>
7 <div id="demo">
8 <table>
9 <tr>
10 <td><label>编号:</label></td>
11 <td><input type="text" v-model="newGoods.id" /></td>
12
13 <td><label>名称:</label></td>
14 <td><input type="text" v-model="newGoods.name" /></td>
15
16 <td><label>类型:</label></td>
17 <td><input type="text" v-model="newGoods.type" /></td>
18
19 <td><label>售价:</label></td>
20 <td><input type="text" v-model="newGoods.price" /></td>
21
22 <td><input type="submit" value="查询" v-on:click="GetGoods(newGoods.id)" /></td>
23 </tr>
24 </table>
25 <table v-show="goodsList.length">
26 <tr>
27 <td>编号</td>
28 <td>名称</td>
29 <td>类型</td>
30 <td>售价</td>
31 </tr>
32 <tr v-for="item in goodsList">
33 <td>{{item.ID}}</td>
34 <td>{{item.Name}}</td>
35 <td>{{item.Type}}</td>
36 <td>{{item.Price}}</td>
37 </tr>
38 </table>
39 </div>
40 <script type="text/javascript">
41 var view = new Vue(
42 {
43 el: "#demo",
44 data: {
45 goodsList: [],
46 newGoods: {id:'',name:'',type:'',price:''}
47 },
48 created: function () {
49 this.InIt();
50 },
51 methods: {
52 InIt: function () {
53 //初始化
54 this.GetAllGoods();
55 },
56 GetAllGoods: function () {
57 var _self = this;
58 _self.$http.get("../Goods/GetAllGoods").then(
59 // Lambda写法
60 (response) => {
61 //successCallback
62 for (var i = 0; i < response.data.length; i++) {
63 _self.goodsList.push(response.data[i]);
64 }
65 } ,
66 (response) => {
67 //errorCallback
68 }
69 );
70 },
71 GetGoods: function (_id) {
72 var _self = this;
73 _self.goodsList = [];
74 if (_id.length > 0) {
75 _self.$http.post("../Goods/GetGoods", { id: _id }).then(
76 // 传统写法
77 function (response) {
78 //successCallback
79 if (response.data.Code == 500) {
80 _self.goodsList.push(response.data.Entity);
81 }
82 else {
83 alert(response.data.Message);
84 }
85 },
86 function (response) {
87 //errorCallback
88 }
89 )
90 .catch(function (response) {
91 console.log(response);
92 });
93 }
94 else {
95 _self.GetAllGoods();
96 }
97 }
98 }
99 }
100 );
101 </script>
2.前端采用axios插件
1 @{
2 Layout = null;
3 }
4
5 <!DOCTYPE html>
6
7 <html>
8 <head>
9 <meta name="viewport" content="width=device-width" />
10 <title>Check</title>
11 <script type="text/javascript" src="~/Resources/Scripts/vue.js"></script>
12 <script type="text/javascript" src="~/Resources/Scripts/axios.min.js"></script>
13 </head>
14 <body>
15 <div id="demo">
16 <div>
17 <table>
18 <tr>
19 <td><label>编号:</label></td>
20 <td><input type="text" v-model="newGoods.id" /></td>
21
22 <td><label>名称:</label></td>
23 <td><input type="text" v-model="newGoods.name" /></td>
24
25 <td><label>类型:</label></td>
26 <td>
27 <select v-model="newGoods.type">
28 <option value="">---ALL---</option>
29 <option v-for="type in goodsType" v-bind:value="type">{{type}}</option>
30 </select>
31 </td>
32
33 <td><label>售价:</label></td>
34 <td><input type="text" v-model="newGoods.price" /></td>
35
36 <td>
37 <input type="submit" value="查询" v-on:click="GetGoods(newGoods.id)" />
38 <input type="submit" value="更新" v-on:click="UpdateGoods(newGoods.id,newGoods.name,newGoods.type,newGoods.price)" />
39 <input type="submit" value="删除" v-on:click="DelectGoods(newGoods.id)" />
40 </td>
41 </tr>
42 </table>
43 </div>
44 <div>
45 <table v-show="goodsList.length">
46 <tr>
47 <td>行号</td>
48 <td>编号</td>
49 <td>名称</td>
50 <td>类型</td>
51 <td>售价</td>
52 </tr>
53 <tr v-for="(item,index) in goodsList">
54 <td>{{index+1}}</td>
55 <td>{{item.ID}}</td>
56 <td>{{item.Name}}</td>
57 <td>{{item.Type}}</td>
58 <td>{{item.Price}}</td>
59 </tr>
60 </table>
61 </div>
62 </div>
63
64
65 <script type="text/javascript">
66 var vm = new Vue({
67 el: "#demo",
68 data: {
69 goodsType:[],
70 goodsList: [],
71 newGoods: { id: '', name: '', type: '', price: '' }
72 },
73 mounted() {
74 this.GetGoodsType();
75 this.GetAllGoods();
76 },
77 methods:
78 {
79 GetGoodsType: function () {
80 axios.get("../Goods/GetGoodsType").then(
81 (response) => {
82 this.goodsType = [];
83 for (var i = 0; i < response.data.length; i++) {
84 this.goodsType.push(response.data[i]);
85 }
86 },
87 (response) => {
88 alert(response.status);
89 }
90 )
91 .catch(function (response) {
92 console.log(response);
93 });
94 } ,
95 GetAllGoods: function () {
96 axios.get('../Goods/GetAllGoods').then(
97 function (response) {
98 vm.goodsList = [];
99 for (var i = 0; i < response.data.length; i++) {
100 vm.goodsList.push(response.data[i]);
101 }
102 //vm.goodsList.splice(response.data.length);
103 },
104 function (response) {
105 alert(response.status);
106 }
107 )
108 .catch(
109 function (error) {
110 alert(error);
111 }
112 )
113 },
114 GetGoods: function (_id) {
115 if (_id.length > 0) {
116 axios.post("../Goods/GetGoods", { id: _id }).then(
117 (response) => {
118 this.goodsList = [];
119 if (response.data.Code == 500) {
120 this.goodsList.push(response.data.Entity);
121 }
122 else {
123 alert(response.data.Message);
124 }
125
126 },
127 (response) => {
128 alert(response.status);
129 }
130 )
131 .catch(function (response) {
132 console.log(response);
133 });
134 }
135 else {
136 this.GetAllGoods();
137 }
138 },
139 UpdateGoods: function (_id,_name,_type,_price) {
140 axios.post("../Goods/UpdateGoods", { entity: { ID: _id, Name: _name, Type: _type, Price: _price } }).then(
141 (response) => {
142 this.goodsList = [];
143 if (response.data.Code == 500) {
144 for (var i = 0; i < response.data.Entity.length; i++) {
145 this.goodsList.push(response.data.Entity[i]);
146 }
147 }
148 else {
149 alert(response.data.Message);
150 }
151 },
152 (response) => {
153 alert(response.status);
154 }
155 )
156 .catch(function (response) {
157 console.log(response);
158 });
159 },
160 DelectGoods: function (_id) {
161 axios.post("../Goods/DelectGoods", { id: _id }).then(
162 (response) => {
163 this.goodsList = [];
164 if (response.data.Code == 500) {
165 for (var i = 0; i < response.data.Entity.length; i++) {
166 this.goodsList.push(response.data.Entity[i]);
167 }
168 }
169 else {
170 alert(response.data.Message);
171 }
172
173 },
174 (response) => {
175 alert(response.status);
176 }
177 )
178 .catch(function (response) {
179 console.log(response);
180 });
181 }
182 },
183
184 });
185 </script>
186 </body>
187 </html>
在上面的视图中,前端都是用数组进行填充的,值得注意的是vue在数组监听这一块做得并不是特别友好。但也提供了一些非常友好的api。
如果你也采用上述方式更新view,请参阅vue官方提供的关于操作数组方法
Perorations:
在上面的Demo中,采用的是ASP.NET MVC模板。在写View部分的时候感觉确实比较方便,不需要再去写获取元素的代码,只需要把数据绑定至元素上,关注数据的变动就可以了。
当然你也可以选择Razor语法,只不过那样看起来并不是很友善。
以上是个人在写这个Demo之后的一些总结。如有描述不当,请@作者修改,谢谢!
