Vue.js——基于$.ajax实现数据的跨域增删查改
概述之前我们学习了Vue.js的一些基础知识,以及如何开发一个组件,然而那些示例的数据都是local的。在实际的应用中,几乎90%的数据是来源于服务端的,前端和服务端之间的数据交互一般是通过ajax请求来完成的。 说起ajax请求,大家第一时间会想到jQuery。除了拥有强大的DOM处理能力,jQuery提供了较丰富的ajax处理方法,它不仅支持基于XMLHttpRequest的ajax请求,也能处理跨域的JSONP请求。 之前有读者问我,Vue.js能结合其他库一起用吗?答案当然是肯定的,Vue.js和jQuery一起使用基本没有冲突,尽可放心大胆地使用。 本文的主要内容如下:
本文的服务端程序和客户端程序是部署在不同服务器上的,本文所有示例请求都是跨域的。源代码已放到GitHub,如果您觉得本篇内容不错,请点个赞,或在GitHub上加个星星! 基础概念在进入本文正题之前,我们需要先了解一些基础概念(如果你已经对这些基础有所了解,可跳过此段落)。 同源策略和跨域概念同源策略(Same-orgin policy)限制了一个源(orgin)中加载脚本或脚本与来自其他源(orgin)中资源的交互方式。 同源之外的请求都可以称之为跨域请求。下表给出了相对同源检测的示例:
跨域资源共享跨域资源共享(CORS)是一份浏览器技术的规范,提供了Web服务器从不同网域传来沙盒脚本的方法,以避开浏览器的同源策略,是JSONP模式的现代版。与JSONP不同,CORS除了支持GET方法以外,还支持其他HTTP方法。用CORS可以让网页设计师用一般的XMLHTTPRequest,这种方式的错误处理比JSONP要来的好。另一方面,JSONP可以在不支持CORS的老旧浏览器上运作,现代的浏览器都支持CORS。 在网页上列出了主流浏览器对CORS的支持情况,包含PC端和移动端的浏览器。
JSONP概念由于同源策略,一般来说不允许JavaScript跨域访问其他服务器的页面对象,但是HTML的 创建和注册modal-dialog组件数据的新建和编辑将使用模态对话框,modal-dialog组件的作用就在于此。 AjaxHelper基于$.ajax声明一个简单的AjaxHelper构造器,AjaxHelper构造器的原型对象包含5个方法,分别用于处理 AjaxHelper.prototype.put = function(url,'PUT',callback) 实现GET请求发送get请求<pre id="bdc2284f2d184195bfa80ef5fa41c7ee" class="javascript" style="display: block">var ajaxHelper = new AjaxHelper() var demo = new Vue({
}) 由于客户端和服务端Web API是分属于不同站点的,它们是不同的源,这构成了跨域请求。这时请求是失败的,浏览器会提示一个错误:????????? 跨域解决方案现在碰到了请求跨域的问题,结合前面讲的一些概念,我们大致可以猜到解决跨域请求的两种方式:
这两种跨域解决方案的区别是什么呢?
选择JSONP还是CORS?除了极少数的情况,我们都应当选择CORS作为最佳的跨域解决方案。 启用CORS在Nuget Package Manager Console下输入以下命令:
添加createCustomer方法:
|
2. 修改simple-grid的methods选项
在simple-grid的methods选项下,添加一个loadEntry
方法,该方法调用$.dispatch向父组件派发事件load-entry
,并将key作为事件的入参,load-entry
是绑定在父组件的事件名称。
3. 修改Vue实例的HTML
在Vue实例的simple-grid标签上绑定自定义事件
load-entry
,load-entry
事件指向loadCustomer
方法,loadCustomer
方法用于加载选中的Customer数据。
我们应将2和3结合起来看,下图阐述了从点击simple-grid数据的链接开始,到最终打开对话框的完整过程:
注意:load-entry
是Vue实例的事件,而不是simple-grid组件的事件,尽管load-entry是写在simple-grid
由于在新建模式和修改模式下标题内容是不同的,因此需要修改modal-dialog的slot="header"
部分。根据item.customerId
是否有值确定修改模式和新建模式,修改模式下显示"Edit Customer - xxx",新建模式下显示"Create New Customer"
<header class="dialog-header" slot="header">
<h1 class="dialog-title">{{ item.customerId ? 'Edit Customer - ' + item.contactName : 'Create New Customer' }}</h1>
</header>
4. 修改Vue实例
为data选项添加title
属性,用于显示对话框的标题。
然后追加3个方法:
loadCustomer
,saveCustomer
和updateCustomer
。<pre id="2b2a3958abcf4155ac84a4b02ae7ef9c" class="javascript" style="display: block">loadCustomer: function(customerId) {
var vm = this
vm.gridData.forEach(function(item) {
if (item.customerId === customerId) {
// 使用$.set设置item
vm.$set('item',item)
return
}
}),vm.$set('show',true)
},saveCustomer: function() {
this.item.customerId ? this.updateCustomer() : this.createCustomer()
this.show = false
},updateCustomer: function() {
// 定义vm变量,让它指向this,callback = function(data) {
// 更新成功后,重新加载页面数据
vm.getCustomers()
}
// 将vm.item直接PUT到服务端
ajaxHelper.put(vm.apiUrl + '/' + vm.item.customerId,callback)
}
saveCustomer
方法根据item.customerId
是否有值确定修改模式和新建模式,如果是新建模式则调用createCustomer
方法,如果是修改模式则调用updateCustomer
方法。
另外,需要将Save按钮的click事件绑定到saveCustomer方法。
5. 添加$watch
使用$watch跟踪data选项show属性的变化,每当关闭对话框时就重置item。
为什么要这么做呢?因为每次打开对话框,不知道是以新建模式还是修改模式打开的,如果不重置item,倘若先以修改模式打开对话框,再以新建模式打开对话框,新建模式的对话框将会显示上次打开的数据。
实现DELETE请求
1. 修改simple-grid组件
在methods选项中添加方法
deleteEntry
:调用
$.dispatch
向父组件派发事件delete-entry
。2. 修改Vue实例的HTML
在simple-grid标签上绑定自定义事件
delete-entry
,该事件指向deleteCustomer
方法。
总结
本篇介绍了同源策略、跨域、CORS和REST等概念,并结合Vue.js和$.ajax实现了一个简单的CURD跨域示例。下一篇,我们将使用Vue的插件vue-resource来完成这些工作。
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!