Overview
Before we learned some of the basics of vue.js and how to develop a component, the data for those samples were local.
In practical applications, almost 90% of the data comes from the server side, and the data interaction between the front end and the server is generally done through AJAX requests.
Speaking of Ajax requests, everyone will think of jquery the first time. In addition to having powerful DOM processing capabilities, jquery provides a richer approach to Ajax processing, which not only supports XMLHttpRequest-based AJAX requests, but also handles cross-domain JSONP requests.
Before a reader asked me, vue.js can be combined with other libraries to use it? The answer is, of course, yes, vue.js and jquery use the basic without conflict, can be assured to use it boldly.
The main contents of this article are as follows:
- Same-origin and cross-domain concepts
- Cross-domain resource sharing
- JSONP concept
- REST Web Services
- Implementing cross-domain get requests based on $.ajax
- Implement JSONP requests based on $.ajax
- Implementing cross-domain post requests based on $.ajax
- Implementing a cross-domain put request based on $.ajax
- Implementing a cross-domain delete request based on $.ajax
The server-side programs and client programs in this article are deployed on different servers, and all sample requests in this article are cross-domain.
The source code has been put on GitHub, if you think this article is good, please click to praise, or add a star on GitHub!
Cors get JSONP get cors POST cors PUT full curd sample GitHub Source basic concept
Before we get to the point of this article, we need to understand some basic concepts (you can skip this paragraph if you already know something about these basics).
Same-origin and cross-domain concepts
The same-orgin policy restricts the way in which a load script or script in one source (orgin) interacts with a resource from another source (Orgin).
If two pages have the same protocol (protocol), Port, and host, then the two pages belong to the same source (Orgin).
Requests outside of the same origin can be called cross-domain requests.
The following table shows an example of relative http://store.company.com/dir/page.html homology detection:
URL |
Results |
cause |
Http://store.company.com/dir2/other.html |
Success |
|
Http://store.company.com/dir/inner/another.html |
Success |
|
Https://store.company.com/secure.html |
Failed |
Different protocols |
Http://store.company.com:81/dir/etc.html |
Failed |
Different ports |
Http://news.company.com/dir/other.html |
Failed |
Host name is different |
we can simply and rudely understand that the resources under the same site are mutually accessible, and that cross-site resource access is cross-domain. cross-domain resource sharing
cross-domain resource sharing (CORS) is a specification of browser technology that provides a way for Web servers to pass sandbox scripts from different domains to circumvent the browser's same-origin policy, which is a modern version of Jsonp mode. Unlike JSONP, Cors supports other HTTP methods in addition to the Get method. Using cors allows web designers to use General XMLHttpRequest, which is better than Jsonp's error handling. On the other hand, JSONP can operate on older browsers that do not support cors, and modern browsers support Cors.
The main browser support for Cors is listed on the Web page http://caniuse.com/#feat =cors, including the PC-and mobile-side browsers.
JSONP concept
Because of the same-origin policy, JavaScript is generally not allowed to access other server's page objects across domains, but the HTML <script> element is an exception. Using this open strategy of <script>, the Web page can get JSON data that is dynamically generated from other sources, and this usage pattern is called JSONP. the data captured with JSONP is not JSON, but arbitrary JavaScript, which executes with a JavaScript interpreter instead of parsing with a JSON parser.
About REST Web Services
HTTP protocol is one of the standards of the Web, the HTTP protocol contains a number of standard methods of operation, such as: and GET, POST, PUT, Delete
so on, using these methods to achieve the curd operation of the Web resources, the following table lists the operation definitions of these methods.
http Method |
Resource Handling |
Description |
GET |
Reading Resources (read) |
gets The information (in the form of an entity) specified by the requested URI (Request-uri). |
POST |
Creating a resource (Create) |
creates a new resource on the server and returns the URI of the new resource. |
PUT |
Updating resources (UPDATE) |
Specifies that the URI resource exists to update the resource, and the specified URI resource does not exist to create a new resource. |
DELETE |
Deleting a resource (delete) |
deletes the resource specified by the request URI. |
In rest applications, the HTTP protocol is passed by default, and the resources are manipulated using the GET, POST, put, and delete methods, which perfectly fit the design style and web standards.
The best scenario for rest is to expose services, use HTTP, and follow the rest principle of Web services, which we call RESTful Web service. RESTful WEB Service defines the resource from the following three aspects:
- Intuitive short resource address: URI, for example: http://example.com/resources/
- Transmitted resources: Web service acceptance and return of the Internet media type, such as Json,xml, etc.
- Operations on resources: a series of request methods supported by Web service on this resource (e.g. get,post,put or delete)
Demonstrates the execution process for RESTful WEB service
The server-side program for this article is built on the ASP. NET Web API.
With these basics in view, let's build server-side programs and client programs separately.
Server-Side Environment readiness
If you are a front-end developer and have not touched the ASP. NET Web API, you can skip this paragraph.
Create a new Web API application
Add model, Controller
Initializing the database
Execute the following 3 commands, respectively:
Let the Web API output JSON in CamelCase
C # is biased toward the pascalcase naming convention, while JavaScript favors the naming conventions of CamelCase, and in order for JavaScript to receive JSON data that is CamelCase, add the following lines of code to the Global.asax file:
var formatters = Globalconfiguration.configuration.formatters;var Jsonformatter = formatters. Jsonformatter;var settings = jsonformatter.serializersettings;settings. formatting = formatting.indented;settings. Contractresolver = new Camelcasepropertynamescontractresolver ();
The built-in web API can be accessed at the following address:
Http://211.149.193.19:8080/Help
Access customers data:
Http://211.149.193.19:8080/api/Customers
Creating Components and Ajaxhelper
The example of this article is still the curd of the tabular component, but this time our data is fetched from the server.
Before we implement the curd of the data, we will first prepare some components and Ajax helper methods.
Creating and registering Simple-grid components
Simple-grid components for binding and displaying data
<template id= "grid-template" ><table><thead><tr><th v-for= "col in columns" >{{col | Capitalize}}</th></tr></thead><tbody><tr v-for= "(index,entry) in DataList" ><td V-for= "col in columns" >{{entry[col]}}</td></tr></tbody></table></template>< Script src= "Js/vue.js" ></script><script>vue.component (' Simple-grid ', {Template: ' #grid-template ', Props: [' dataList ', ' columns ']}) </script>
Creating and registering Modal-dialog components
The new and edited data will use the modal dialog box, which is what the Modal-dialog component does.
<template id= "dialog-template" ><div class= "dialogs" ><div class= "dialog" v-bind:class= "{' Dialog-active ': Show} "><div class=" dialog-content "><div class=" close rotate "><span class=" Iconfont icon-close "@click =" Close "></span></div><slot name=" header "></slot><slot Name= "Body" ></slot><slot name= "footer" ></slot></div></div><div class= " Dialog-overlay "></div></div></template><script>vue.component (' Modal-dialog ', { Template: ' #dialog-template ', props: [' Show '],methods: {close:function () {this.show = False}}}) </script>
Ajaxhelper
Based on the $.ajax declaration of a simple Ajaxhelper constructor, the prototype object of the Ajaxhelper constructor contains 5 methods, respectively, for processing a GET, POST, PUT, DELETE和JSONP
request.
function Ajaxhelper () {this.ajax = function (URL, type, DataType, data, callback) {$.ajax ({Url:url,type:type,datatype:da Tatype,data:data,success:callback,error:function (XHR, ErrorType, error) {alert (' Ajax request error, ErrorType: ' + erro Rtype + ', error: ' + Error '}})}}ajaxhelper.prototype.get = function (URL, data, callback) {This.ajax (URL, ' Get ', ' json ', data, callback)}ajaxhelper.prototype.post = function (URL, data, callback) {This.ajax (URL, ' post ', ' JSON ', data, Callba CK)}ajaxhelper.prototype.put = function (URL, data, callback) {This.ajax (URL, ' Put ', ' json ', data, callback)} AjaxHelper.prototype.delete = function (URL, data, callback) {This.ajax (url, ' delete ', ' json ', data, callback)} AjaxHelper.prototype.jsonp = function (URL, data, callback) {This.ajax (URL, ' GET ', ' Jsonp ', data, callback)} AjaxHelper.prototype.constructor = Ajaxhelper
Implementing a GET request to send a GET request
var ajaxhelper = new Ajaxhelper () var demo = new Vue ({el: ' #app ', data: {gridcolumns: [' customerId ', ' companyName ', ' contact Name ', ' phone '],griddata: [],apiurl: ' Http://localhost:15341/api/Customers '},ready:function () {this.getcustomers () },methods: {getcustomers:function () {//} Define VM variable so that it points to This,this is the current Vue instance var vm = This,callback = function (data) {///due to function Domain, you cannot use THISVM. $set (' Griddata ', data)}ajaxhelper.get (Vm.apiurl, NULL, Callback)}})
Because the client and server Web APIs belong to different sites, they are different sources, which constitute cross-domain requests.
At this point the request is unsuccessful and the browser will prompt an error:
No ' Access-control-allow-origin ' header is present on the requested resource. Origin ' http://127.0.0.1::8020 ' is therefore not allowed access.
Cross-Domain Solutions
Now that we have a cross-domain problem, and in conjunction with some of the previous concepts, we can roughly guess two ways to resolve cross-domain requests:
- Enable cors on the server side.
- Let no server have the ability to handle JSONP.
What is the difference between these two cross-domain solutions?
- JSONP only supports get requests; Cors supports standard HTTP methods such as GET, POST, PUT, delete, and so on
- When using JSONP, the server handles the callback parameter of the client request (the name "callback" can be specified), while using cors does not need to provide such processing.
- JSONP is a script file obtained from the server, and Cors is a piece of XML or JSON or other format data
- JSONP supports IE8, IE9 retro browsers, and Cors supports modern mainstream browsers
Choose Jsonp or Cors? In rare cases, we should choose Cors as the best cross-domain solution.
Enable Cors
Enter the following command under NuGet package Manager console:
Install-package Microsoft.AspNet.WebApi.Cors
Add Enablecors features on Customerscontroller, Origins, headers, and methods are set to *
[Enablecors (Origins: "*", Headers: "*", Methods: "*")]public class customerscontroller:apicontroller{}
The Web API configuration instructions and principles, the following address is very clear:
Http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api
Refresh the page, now the data can be displayed properly.
View Demo
Under the network option of the Chrome development tool, you can see that the content-type of the response header is Application/json.
The article begins by saying that Cors's cross-domain approach supports modern mainstream browsers, but does not support IE9 and the following classic browsers.
What if we want to implement cross-domain access in IE9 browser (Vue.js does not support IE8 and the following browsers, so do not consider IE 6,7,8)?
The answer is to use the JSONP request.
Implementing JSONP Requests
Change the GET request for the GetCustomers method to the JSONP request:
Getcustomers:function () {///define VM variable so that it points to This,this is the current Vue instance var vm = This,callback = function (data) {///due to the scope of the function, You can't use THISVM. $set (' Griddata ', data)}ajaxhelper.jsonp (Vm.apiurl, NULL, callback)}
Refresh the page, although the request succeeds, but the screen does not display the data, and the request error message pops up.
Let WEBAPI support JSONP request
Enter the following command in NuGet Package Manager:
Install-package WebApiContrib.Formatting.Jsonp
Then register the Jsonpmediatypeformatter in the Global.asax Application_Start () method:
Register Jsonpmediatypeformatter, allow WEBAPI to process JSONP request Config.Formatters.Insert (0, New Jsonpmediatypeformatter ( Jsonformatter));
Refresh the page and use the JSONP request to display the data normally.
Note: When using JSONP, the server returns no longer a JSON, but a script.
Viewing the page under IE9, the Simple-grid component can also display the data normally:
View Demo
Implement POST request 1. Create Form dialog box
Add a Create button, and then use the Modal-dialog component to create a Form dialog box:
<div id= "App" ><!--... Omitted--><div class= "container" ><div class= "Form-group" ><button @click = "This.show = True" >create </button></div></div><modal-dialog v-bind:show.sync= "Show" >Note: When you create a new customer, the Item.customerid associated form is not displayed because Item.customerid is empty, and the Item.customerid associated form is displayed when you modify the customer. In addition, Item.customerid is not editable.
2. Modifying the Vue instancevar demo = new Vue ({el: ' #app ', data: {show:false,gridcolumns: [{name: ' CustomerId ', iskey:true}, {name: ' CompanyName '}, { Name: ' ContactName '}, {name: ' phone '}],griddata: [],apiurl: ' Http://localhost:15341/api/Customers ', item: {}},ready: function () {this.getcustomers ()},methods: {//... Omitted createcustomer:function () {var vm = This,callback = function (data) {vm. $set (' item ', {})//Added successfully, Reload page Data vm.getcustomers ()}//post Vm.item directly to server Ajaxhelper.post (Vm.apiurl, Vm.item, callback) This.show = False}})
To modify the data option for the Vue instance:
- Add
show
property: Use to Show or hide Form dialog boxes
- Modify
gridColumns
Property: column contains two attributes, name represents column name, IsKey indicates whether the column is a primary key column
- Add
item
property: For new customer or modify customer
To add the CreateCustomer method:
Createcustomer:function () {var vm = This,callback = function (data) {vm. $set (' item ', {})//Reload the page data after a successful addition vm.getcustomers ()}//post Vm.item directly to server Ajaxhelper.post (Vm.apiurl, Vm.item, callback) This.show = False}
View Demo
Implement put request 1. Modify the template for Sample-grid
Adds a link to the primary key column, binds the click event, the event points to the Loadentry method, and the Loadentry method to load the currently selected data.
<template id= "grid-template" ><table><thead><tr><th v-for= "col in columns" >{{col.name | Capitalize}}</th></tr></thead><tbody><tr v-for= "(index,entry) in DataList" ><td V-for= "col in columns" ><span v-if= "Col.iskey" ><a href= "javascript:void (0)" @click = "Loadentry (entry[ Col.name]) ">{{Entry[col.name]}}</a></span><span v-else>{{Entry[col.name]}}</span> </td></tr></tbody></table></template>
2. Modify the Simple-grid methods option
Under the methods option for Simple-grid, add a loadEntry
method that calls $.dispatch to distribute the event to the parent component load-entry
and use the key as the argument for the event, which load-entry
is the event name that is bound to the parent component.
Vue.component (' Simple-grid ', {Template: ' #grid-template ', props: [' dataList ', ' columns '],methods: {loadentry: function (key) {this. $dispatch (' Load-entry ', Key)}})
3. Modifying the HTML of the Vue instance
A custom event is bound on the simple-grid tag of the Vue instance load-entry
, the load-entry
event points to the loadCustomer
method, and loadCustomer
the method is used to load the selected customer data.
<div id= "App" ><!--... Omitted--><div class= "container" ><simple-grid:d ata-list= "griddata": columns= "Gridcolumns" V-on:load-entry = "Loadcustomer" ></simple-grid></div><!--... --></div> has been omitted
We should combine 2 and 3 to look at the complete process of starting a link from clicking on the Simple-grid data to the final Open dialog box:
Note: load-entry
Is the event of the Vue instance, not the event of the Simple-grid component, although Load-entry is written on the Simple-grid
label. For more information, please refer to the compilation scope of the previous article
Because the header content is different in the new and modified modes, you need to modify the section of the Modal-dialog slot="header"
.
Depending on item.customerId
whether there is a value to determine the modification mode and the new mode, the Modify mode displays "Edit Customer-xxx", and the new mode displays "Create New Customer"
<modal-dialog v-bind:show.sync= "Show" >
4. Modifying the Vue instanceAdds a property for the data option to title
display the caption of the dialog box.
var demo = new Vue ({el: ' #app ', data: {//... The title has been omitted: '//... Omitted}//... omitted})
Then add 3 methods: loadCustomer
, saveCustomer
and updateCustomer
.
Loadcustomer:function (customerId) {var vm = Thisvm.gridData.forEach (function (item) {if (Item.customerid = = = CustomerId ) {//Use $.set to set ITEMVM. $set (' item ', item) return}), VM. $set (' show ', True)},savecustomer:function () { This.item.customerId? This.updatecustomer (): This.createcustomer () this.show = False},updatecustomer:function () {//define VM variable to point to this, This is the current Vue instance var vm = This,callback = function (data) {////After the update succeeds, reload the page Data vm.getcustomers ()}// Put Vm.item directly to server ajaxhelper.put (Vm.apiurl + '/' + vm.item.customerId, Vm.item, Callback)}
saveCustomer
Method according toitem.customerId
Whether there is a value to determine the Modify mode and new mode, and if new mode is calledcreateCustomer
method, or if the schema is modified, call theupdateCustomer
Method.In addition, you need to bind the click event of the Save button to the Savecustomer method.
<div class= "Dialog-body" slot= "Body" ><!--... Omitted--><div class= "Form-group" ><label></label><button @click = "Savecustomer" >Save</ button></div><!--... --></div> has been omitted
5. Add $watchUse $watch to track the change in the show property of the data option and reset the item whenever the dialog box is closed.
Demo. $watch (' Show ', function (newval, oldval) {if (!newval) {This.item = {}}})
Why did you do it? Because each time you open the dialog box and do not know whether to open in new or modified mode, if you do not reset item, if you open the dialog box in modify mode, and then open the dialog box in new mode, the dialog box for the new mode will display the last Open data.
View Demo
Implement delete request 1. Modifying the Simple-grid componentTo add a method to the methods option deleteEntry
:
Deleteentry:function (Entry) {this. $dispatch (' delete-entry ', entry)}
Called $.dispatch
to dispatch events to the parent component delete-entry
.
2. Modifying the HTML of the Vue instanceThe custom event is bound to the Simple-grid tag delete-entry
, which points to the deleteCustomer
method.
<div id= "App" ><!--... Omitted--><div class= "container" ><simple-grid:d ata-list= "griddata": columns= "Gridcolumns" V-on:load-entry = "Loadcustomer" v-on:delete-entry= "DeleteCustomer" ></simple-grid></div><!--... --></div> has been omitted
View Demo
SummarizeThis article introduces the concepts of homologous policy, cross-domain, cors, and rest, and implements a simple curd cross-domain example with vue.js and $.ajax.
Next, we'll use Vue's plugin vue-resource to do the work.
vue.js--cross-domain additions and deletions based on $.ajax realization data