ASP.NET MVC+Vue.js实现联系人管理

接触了一天 vue.js,简单浏览了一本关于 vue 的电子书,就开始动手使用 ASP.NET MVC 和 Vue.js 开发一个联系人管理的小程序。

先看一下这个联系人管理的小程序的界面,也就是我们大概要实现什么样的功能。

上面截图可以看出,这是一个很简单的表格管理功能。我们先分析一下,上述有哪些功能需要实现:

1、默认先加载出所有的联系人信息,有信息的行后面的操作那一栏,显示“修改”、“删除”,没有信息的行后面的操作那一栏,显示“添加”(默认只添加一行需要添加的信息)。

2、点击“添加”按钮对应的空白文本框中的内容,即可完成添加联系人的操作。添加操作完成后,自动添加一行空白行,以便再次添加。

3、编辑任意文本框中的内容,点击对应行后面的“修改”按钮,即可完成修改操作。

4、点击“删除”按钮,即可删除对应行的联系人记录

 

大家可以先思考一下,如果就单独使用 ASP.NET MVC,不使用任何 JS 或 jQuery 插件,怎么完成。

下面就开始要正式实现上面的功能,首先我们要准备好后端的内容,就是 Model、Controller、Repository 这些内容。

Model 很简单,就一个联系人的类:

public class Contact
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string PhoneNo { get; set; }
    public string EmailAddress { get; set; }
}

然后新建一个 ContactRepository 类,用来提供数据的 CRUD 操作(这里只是简单的将数据封装到 static 变量中):

public class ContactRepository
{
    private static List<Contact> contacts;
</span><span style="color: rgba(0, 0, 255, 1)">static</span><span style="color: rgba(0, 0, 0, 1)"> ContactRepository()
{
    contacts </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> List&lt;Contact&gt;<span style="color: rgba(0, 0, 0, 1)">()
    {
        </span><span style="color: rgba(0, 0, 255, 1)">new</span> Contact(){ Id=Guid.NewGuid().ToString(), Name=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">张三</span><span style="color: rgba(128, 0, 0, 1)">"</span>, PhoneNo=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">123</span><span style="color: rgba(128, 0, 0, 1)">"</span>, EmailAddress=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">zhangsan@gmail.com</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)"> },
        </span><span style="color: rgba(0, 0, 255, 1)">new</span> Contact(){ Id=Guid.NewGuid().ToString(), Name=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">李四</span><span style="color: rgba(128, 0, 0, 1)">"</span>, PhoneNo=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">456</span><span style="color: rgba(128, 0, 0, 1)">"</span>, EmailAddress=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">lisi@gmail.com</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)"> },
    };
}

</span><span style="color: rgba(0, 0, 255, 1)">public</span> IEnumerable&lt;Contact&gt;<span style="color: rgba(0, 0, 0, 1)"> Get()
{
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> contacts;
}

</span><span style="color: rgba(0, 0, 255, 1)">public</span> Contact Get(<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> id)
{
    </span><span style="color: rgba(0, 0, 255, 1)">return</span> contacts.FirstOrDefault(t =&gt; t.Id ==<span style="color: rgba(0, 0, 0, 1)"> id);
}

</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> Put(Contact contact)
{
    contact.Id </span>=<span style="color: rgba(0, 0, 0, 1)"> Guid.NewGuid().ToString();
    contacts.Add(contact);
}

</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> Post(Contact contact)
{
    Delete(contact.Id);
    contacts.Add(contact);
}

</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> Delete(<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> id)
{
    Contact contact </span>= contacts.FirstOrDefault(t =&gt; t.Id ==<span style="color: rgba(0, 0, 0, 1)"> id);
    contacts.Remove(contact);
}

}

接下来就是 ContactController 控制器:

public class ContactController : Controller
{
    private static ContactRepository contactRepository = new ContactRepository();
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> ActionResult Index()
{
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> View();
}

[HttpGet]
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> JsonResult Get()
{
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> Json(contactRepository.Get(), JsonRequestBehavior.AllowGet);
}

[HttpPost]
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> JsonResult Add(Contact contact)
{
    contactRepository.Put(contact);
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> Json(contactRepository.Get());
}

[HttpPost]
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> JsonResult Update(Contact contact)
{
    contactRepository.Post(contact);
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> Json(contactRepository.Get());
}

[HttpPost]
</span><span style="color: rgba(0, 0, 255, 1)">public</span> JsonResult Delete(<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> id)
{
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> contact =<span style="color: rgba(0, 0, 0, 1)"> contactRepository.Get(id);
    contactRepository.Delete(id);
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> Json(contactRepository.Get());
}

}

控制器中的代码也非常简单,就是简单的提供了 CRUD 对应的 Action 方法。

上述的操作,是 ASP.NET MVC 中的常规操作,也可以说是套路。完成了后端(ASP.NET MVC)开发工作,下面就是前端(Vue)开发工作了。

要在项目中使用 Vue,首先要导入 Vue 的 js 文件,可以直接将 Vue.js 拷贝到 Scripts 目录中。此外由于我们需要在 cshtml 中发起 ajax 请求,调用 controller 中的各种 action 方法,因此我们也需要引用 vue 的 ajax 插件 -axios。它们都可以通过 NuGet 在线安装。引用 vue、axios 后的目录截图如下:

联系人页面代码(Index.cshtml):

@{Layout = null;}

<!DOCTYPE html>

<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>联系人管理</title>
<link href="~/Content/bootstrap.css" rel="stylesheet" />
<script src="~/Scripts/vue.js"></script>
<script src="~/Scripts/axios.js"></script>
<style type="text/css">
table
{
margin
: 10px auto auto 10px;
}
</style>
</head>
<body>
<div id="app">
<table v-show="contactsList.length" class="table-condensed" border="1">
<thead class="navbar-header">
<tr>
<th>姓名</th>
<th>电话号码</th>
<th>Email 地址</th>
<th>操作</th>
</tr>
<tr v-for="(contact,index) in contactsList">
<td><input type="text" v-model="contact.Name" /></td>
<td><input type="text" v-model="contact.PhoneNo" /></td>
<td><input type="text" v-model="contact.EmailAddress" /></td>
<td>
<div v-if="contact.Id!=''">
<a href="#" v-on:click="updateContact(contact.Id,contact.Name,contact.PhoneNo,contact.EmailAddress)">修改</a>
<a href="#" v-on:click="deleteContactById(contact.Id)">删除</a>
</div>
<div v-else>
<a href="#" v-on:click="addContact(contact.Name,contact.PhoneNo,contact.EmailAddress)">添加</a>
</div>
</td>
</tr>
</thead>
</table>
</div>
<script type="text/javascript">
var vm = new Vue({
el:
"#app",
data: {
contactsList:[]
},
mounted() {
this.getAllContacts();
},
methods: {
getAllContacts:
function () {
axios.get(
'@Url.Action("Get", "Contact")'
).then(
(response)
=> {
this.contactsList = [];
for (var i = 0; i < response.data.length; i++) {
this.contactsList.push(response.data[i]);
}
this.contactsList.push({ Id:"", Name: "", PhoneNo: "", EmailAddress: "" });
},
(response)
=> {
alert(response.status);
}
).
catch(function (response) {
alert(response);
});
},
addContact:
function (name, phoneno, emailaddress) {
axios.post(
'@Url.Action("Add", "Contact")', {contact: { Name: name, PhoneNo: phoneno, EmailAddress: emailaddress} }).then(
(response)
=> {
this.contactsList = [];
for (var i = 0; i < response.data.length; i++) {
this.contactsList.push(response.data[i]);
}
this.contactsList.push({ Id: "", Name: "", PhoneNo: "", EmailAddress: "" });
},
(response)
=> {
alert(response.status);
}
).
catch(function (response) {
alert(response);
});
},
updateContact:
function (id, name, phoneno, emailaddress) {
axios.post(
'@Url.Action("Update", "Contact")', {contact: { Id: id, Name: name, PhoneNo: phoneno, EmailAddress: emailaddress} }).then(
(response)
=> {
this.contactsList = [];
for (var i = 0; i < response.data.length; i++) {
this.contactsList.push(response.data[i]);
}
this.contactsList.push({ Id: "", Name: "", PhoneNo: "", EmailAddress: "" });
},
(response)
=> {
alert(response.status);
}
).
catch(function (response) {
alert(response);
});
},
deleteContactById:
function (id) {
axios.post(
'@Url.Action("Delete", "Contact")', {id: id}).then(
(response)
=> {
this.contactsList = [];
for (var i = 0; i < response.data.length; i++) {
this.contactsList.push(response.data[i]);
}
this.contactsList.push({ Id: "", Name: "", PhoneNo: "", EmailAddress: "" });
},
(response)
=> {
alert(response.status);
}
).
catch(function (response) {
alert(response);
});
}
}
});
</script>
</body>
</html>

上述代码有几个需要说明的地方:

1、js 部分:

a)我们将 crud 操作,封装到了一个 vue 对象当中。

b)mounted 方法涉及到 vue 对象的生命周期(限于篇幅,这里不展开),但要知道一点 mounted 方法一般会将 ajax 初始化数据操作放在其中。

c)axios 插件的 ajax 请求操作(比如:get、post)可以看下相关的开发文档,基本上看下例子就能上手开发。

2、html 部分:

html 部分用到了一些 vue 指令,比如 v-for(遍历对象列表)、v-if / v-else(条件判断)、v-show(是否显示,带表达式)、v-model(模型绑定)。这部分知识是 vue 的核心知识,这里限于篇幅,不再细讲。先基本会用即可。

 

总结:通过这个程序可以发现 Vue 的一个很大的优点,就是使用 Vue 后真正做到了所谓的前后端分离。前端页面完全看不到夹渣的 C# 后端代码,代码显示很干净整洁。当然 Vue 还有其它优点,比如:相对容易学习(angular、react),虚拟 dom、组件式开发,基于 MVVM 的数据双向绑定,Vue.js 文件很小,插件丰富、对应的阿里移动端 Vue.js 解决方案 -weex 等等,还是非常值得学习和应用的,怪不得当前 Vue.js 这么火热。

 

最后有一个坑需要注意一下,就是 js 部分调用后台 controller 中的 action 时,传递参数是这样的:

{ contact: {Id: id, Name: name, PhoneNo: phoneno, EmailAddress: emailaddress}

对应的 Controller 的 Update 方法是这样的:

[HttpPost]
public JsonResult Update(Contact contact)
{contactRepository.Post(contact);
    return Json(contactRepository.Get());
}

其中的变量名,一定要一致,否则后台 Controller 中的 Update 方法接收不到前端页面传入的值。

 

代码下载链接:https://pan.baidu.com/s/1EmJfwceYKiXZu0mPRCyXhQ 密码:q9o3