I. axios
When Vue is updated to 2.0, it is declared that it will no longer update vue-resource. It is recommended to use axios, a component for client-server communication, and axios, an HTTP client javaScript tool based on Promise for browsers and nodejs. Generally speaking, the client can request the service provided by the server to obtain data.
Source code and help: https://github.com/axios/axios
Server-side cross-domain support please see: http://www.cnblogs.com/best/p/6196202.html#_label2
1.1, characteristics
- Create XMLHttpRequest from Browser
- Issue http requests from node.js
- Support for Promise API
- Intercept requests and responses
- Transform request and response data
- Cancellation request
- Automatic conversion of JSON data
- Client support prevents CSRF/XSRF
1.2. Browser Compatibility
1.3. Dependence
$ npm install axios $ cnpm install axios //taobao $ bower install axios //Or use cdn: <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
Browsers can introduce js files
1.4. Quick Start
1.4.0, server side
Controller:
package com.zhangguo.springmvc08.controller; import com.zhangguo.springmvc08.entity.User; import com.zhangguo.springmvc08.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.List; @RestController @RequestMapping(path = "/emps") public class EmpController extends BaseController { @Autowired UserService userService; @RequestMapping(path = "") public AjaxState getAllEmps(HttpServletRequest request, HttpServletResponse response) { List<User> users=userService.queryAllUsers(); boolean result=users!=null; return new AjaxState(result?"success":"error",users,result?"Data Success!":"Failure to obtain data!"); } @RequestMapping(path = "/{id}", method = RequestMethod.GET) public AjaxState getEmpById(@PathVariable int id) { User user=userService.getUserById(id); boolean result=user!=null; return new AjaxState(result?"success":"error",user,result?"Data Success!":"Failure to obtain data!"); } @RequestMapping(path = "/getEmpById", method = RequestMethod.GET) public AjaxState getEmpById(HttpServletRequest request) { int id=Integer.parseInt(request.getParameter("id")); User user=userService.getUserById(id); boolean result=user!=null; return new AjaxState(result?"success":"error",user,result?"Data Success!":"Failure to obtain data!"); } @RequestMapping(path = "", method = RequestMethod.POST) public AjaxState addEmp(@RequestBody User user) { boolean result=userService.addUser(user); return new AjaxState(result?"success":"error",user,result?"Add success!":"Add failure"); } @RequestMapping(path = "", method = RequestMethod.PUT) public AjaxState updateEmp(@RequestBody User user) { boolean result=userService.editUser(user); return new AjaxState(result?"success":"error",user,result?"Successful revision!":"Modification failed"); } @RequestMapping(path = "/{id}", method = RequestMethod.DELETE) public AjaxState deleteEmpById(@PathVariable int id) { Boolean result=userService.deleteUser(id); return new AjaxState(result?"success":"error",id,result?"Delete successfully!":"Delete failed"); } } class AjaxState{ public String state; public Object data; public String message; public AjaxState(String state, Object data, String message) { this.state = state; this.data = data; this.message = message; } public AjaxState(){} }
Cross-domain settings (optional one):
Method 1: Servlet, MVC, Web.xml
<filter> <filter-name>CORS</filter-name> <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class> <init-param> <param-name>cors.allowOrigin</param-name> <param-value>http://127.0.0.1:8020</param-value> </init-param> <init-param> <param-name>cors.supportedMethods</param-name> <param-value>POST,GET,OPTIONS,DELETE,PUT</param-value> </init-param> <init-param> <param-name>cors.supportedHeaders</param-name> <param-value>Content-Type,Accept,Origin,XRequestedWith,ContentType,LastModified</param-value> </init-param> <init-param> <param-name>cors.exposedHeaders</param-name> <param-value>SetCookie</param-value> </init-param> <init-param> <param-name>cors.supportsCredentials</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>CORS</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
Method 2: Spring MVC, modify Spring configuration file, low Spring version does not support
<mvc:cors> <mvc:mapping path="/**" allowed-origins="http://127.0.0.1:8020" allowed-methods="POST,GET, OPTIONS,DELETE,PUT" allowed-headers="Content-Type,ContentType,Access-Control-Allow-Headers, Authorization, X-Requested-With" allow-credentials="true"/> </mvc:cors>
1.4.1. Send Get Request
//To have specified ID Users make requests axios.get('/user?ID=123') .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); }); //It can also be passed through params Object Transfer Parameters axios.get('/user', { params: { ID: 12345 } }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });
Example:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>axios</title> </head> <body> <div id="vm"> <button type="button" @click="get">Get request</button> <button type="button" @click="getParam">Get Request with parameters</button> <h3>{{msg}}</h3> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script src="../js/axios/axios.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var vm = new Vue({ el: "#vm", data: { msg: "" }, methods: { get: function() { var that = this; axios.get("http://localhost:8080/mvc08/emps").then(function(response) { console.log(response); //this.msg=JSON.stringify(response.data); //Error this points to window vm.msg = JSON.stringify(response.data); that.msg = JSON.stringify(response.data); }).catch(function(error) { console.log(error); }) }, getParam: function() { axios.get("http://localhost:8080/mvc08/emps/getEmpById", { params: { id: 1 } }).then(function(response) { vm.msg = JSON.stringify(response.data); }).catch(function(error) { console.log(error); }) } } }); </script> </body> </html>
Result:
get request
With parameters:
The default content-type is: application/json;charset=UTF-8
1.4.2. Send Post Request
axios.post('/user', { firstName: 'Fred', lastName: 'Flintstone' }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });
Example (add a user):
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>axios</title> </head> <body> <div id="vm"> <button type="button" @click="get">Get request</button> <button type="button" @click="getParam">Get Request with parameters</button> <button type="button" @click="post">Post Request with parameters</button> <h3>{{msg}}</h3> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script src="../js/axios/axios.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var vm = new Vue({ el: "#vm", data: { msg: "" }, methods: { get: function() { //get request var that = this; axios.get("http://localhost:8080/mvc08/emps").then(function(response) { console.log(response); //this.msg=JSON.stringify(response.data); //Error this points to window vm.msg = JSON.stringify(response.data); that.msg = JSON.stringify(response.data); }).catch(function(error) { console.log(error); }) }, getParam: function() { //Parameterized get axios.get("http://localhost:8080/mvc08/emps/getEmpById", { params: { id: 1 } }).then(function(response) { vm.msg = JSON.stringify(response.data); console.log(response); }).catch(function(error) { console.log(error); }) }, post: function() { //post var user = { "id": 1, "name": "Zhang Yi San", "birthday": "1998-09-08", "address": "Beijing China", "phone": "18989891122" }; axios .post("http://localhost:8080/mvc08/emps", user) .then(function(response) { vm.msg=response.data.data; console.log(response); }) .catch(function(error){ console.log(error); }); } } }); </script> </body> </html>
Result:
1.4.3. Sending multiple concurrent requests
function getUserAccount() { return axios.get('/user/12345'); } function getUserPermissions() { return axios.get('/user/12345/permissions'); } axios.all([getUserAccount(), getUserPermissions()]) .then(axios.spread(function (acct, perms) { //Two requests have now been completed }));
Examples (students numbered 1 and 2 are obtained simultaneously, through two requests):
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>axios</title> </head> <body> <div id="vm"> <button type="button" @click="all">all Request (concurrent request)</button> <h3>{{msg}}</h3> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script src="../js/axios/axios.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var vm = new Vue({ el: "#vm", data: { msg: "" }, methods: { all:function(){ //Get user object 1 var getUser1=function(){ return axios.get("http://localhost:8080/mvc08/emps/1"); }; //Get user object 2 var getUser2=function(){ return axios.get("http://localhost:8080/mvc08/emps/2"); }; //Concurrent request processing results axios.all([getUser1(),getUser2()]) .then(axios.spread(function(response1,response2){ var result=""; result+=JSON.stringify(response1.data.data); result+=JSON.stringify(response2.data.data); vm.msg=result; })) .catch(function(error){ console.log(error); }); } } }); </script> </body> </html>
Result:
1.4.4. Send Put requests
Example (modifying user information numbered 1):
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>axios</title> </head> <body> <div id="vm"> <button type="button" @click="all">all Request (concurrent request)</button> <button type="button" @click="put">put Request (modify data)</button> <h3>{{msg}}</h3> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script src="../js/axios/axios.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var vm = new Vue({ el: "#vm", data: { msg: "" }, methods: { all: function() { //Get user object 1 var getUser1 = function() { return axios({ url:"http://localhost:8080/mvc08/emps/1", method:"get" }); }; //Get user object 2 var getUser2 = function() { return axios.get("http://localhost:8080/mvc08/emps/2"); }; //Concurrent request processing results axios.all([getUser1(), getUser2()]) .then(axios.spread(function(response1, response2) { var result = ""; result += JSON.stringify(response1.data.data); result += JSON.stringify(response2.data.data); vm.msg = result; })) .catch(function(error) { console.log(error); }); }, put: function() { var user = { "id": 1, "name": "Zhang Xue Ba", "birthday": "1988-09-08", "address": "Zhuhai, China", "phone": "13223456786" }; axios.put("http://localhost:8080/mvc08/emps",user) .then(r=>vm.msg=r.data.data) .catch(e=>console.log(e)); } } }); </script> </body> </html>
Result:
1.4.5, Delete request
Example (delete user number 2):
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>axios</title> </head> <body> <div id="vm"> <button type="button" @click="all">all Request (concurrent request)</button> <button type="button" @click="remove">delete Request (delete data)</button> <h3>{{msg}}</h3> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script src="../js/axios/axios.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var vm = new Vue({ el: "#vm", data: { msg: "" }, methods: { all: function() { //Get user object 1 var getUser1 = function() { return axios({ url:"http://localhost:8080/mvc08/emps/1", method:"get" }); }; //Get user object 2 var getUser2 = function() { return axios.get("http://localhost:8080/mvc08/emps/2"); }; //Concurrent request processing results axios.all([getUser1(), getUser2()]) .then(axios.spread(function(response1, response2) { var result = ""; result += JSON.stringify(response1.data.data); result += JSON.stringify(response2.data.data); vm.msg = result; })) .catch(function(error) { console.log(error); }); }, remove: function() { axios.delete("http://localhost:8080/mvc08/emps/2") .then(r=>vm.msg=r.data.data) .catch(e=>console.log(e)); } } }); </script> </body> </html>
Result:
1.3. Help Notes (API)
Requests can be made by passing the configuration to axios.
1.3.1,axios(config)
//Send one POST request axios({ method: 'post', url: '/user/12345', data: { firstName: 'Fred', lastName: 'Flintstone' } });
1.3.2,axios(url[, config])
// Send one GET request (GET Request is the default request mode) axios('/user/12345');
1.3.3. Request method alias
For convenience, aliases have been provided for all supported request methods.
axios.request(config) axios.get(url [,config]) axios.delete(url [,config]) axios.head(url [,config]) axios.post(url [,data [,config]]) axios.put(url [,data [,config]]) axios.patch(url [,data [,config]])
Note that when using alias methods, you do not need to specify url, method, and data attributes in config.
1.3.4, Concurrent
Help functions handle concurrent requests.
axios.all(iterable)
axios.spread(callback)
1.3.5. Create an instance
You can use custom configurations to create new instances of axios.
axios.create([config])
var instance = axios.create({ baseURL: 'https://some-domain.com/api/', timeout: 1000, headers: {'X-Custom-Header': 'foobar'} });
Example (custom instance $$, instead of axios, unified url):
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>axios</title> </head> <body> <div id="vm"> <button type="button" @click="all">all Request (concurrent request)</button> <button type="button" @click="remove">delete Request (delete data)</button> <h3>{{msg}}</h3> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script src="../js/axios/axios.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> //Create custom axios Example var $$=axios.create({ baseURL:"http://localhost:8080/mvc08/emps/" }); console.log($$); var vm = new Vue({ el: "#vm", data: { msg: "" }, methods: { all: function() { //Get user object 1 var getUser1 = function() { return $$({ url:"1", method:"get" }); }; //Get user object 2 var getUser2 = function() { return $$.get("24"); }; //Concurrent request processing results axios.all([getUser1(), getUser2()]) .then(axios.spread(function(response1, response2) { var result = ""; result += JSON.stringify(response1.data.data); result += JSON.stringify(response2.data.data); vm.msg = result; })) .catch(function(error) { console.log(error); }); }, remove: function() { $$.delete("2") .then(r=>vm.msg=r.data.data) .catch(e=>console.log(e)); } } }); </script> </body> </html>
Result:
1.3.6. Example method
The available example methods are shown below. The specified configuration will be merged with the instance configuration.
axios#request(config) axios#get(url [,config]) axios#delete(url [,config]) axios#head(url [,config]) axios#post(url [,data [,config]]) axios#put(url [,data [,config]]) axios#patch(url [,data [,config]])
1.3.7, Request Configuration
These are available configuration options for making requests. Only URLs are required. If no method is specified, the request defaults to GET.
{ // `url`Is the server used for requests URL url: '/user', // `method`Is the request method used when making a request method: 'get', // default // `baseURL`Will be added to`url`In front, unless`url`It's absolute. // Easy to do axios Instance settings`baseURL`,In order to be relative URL Method passed to the instance. baseURL: 'https://some-domain.com/api/', // `transformRequest`Allow changes to request data before it is sent to the server // This applies only to request methods'PUT','POST'and'PATCH' // The last function in the array must return a string, a ArrayBuffer Or a Stream transformRequest: [function (data) { // Do any data conversion you want return data; }], // `transformResponse`Allow in then / catch Previous changes to response data transformResponse: [function (data) { // Do whatever you want to transform the data return data; }], // `headers`To send a custom headers headers: {'X-Requested-With': 'XMLHttpRequest'}, // `params`To be sent with the request URL parameter // Must be a pure object or URLSearchParams object params: { ID: 12345 }, // `paramsSerializer`Is an optional function responsible for serialization`params` // (e.g. https://www.npmjs.com/package/qs, http://api.jquery.com/jquery.param/) paramsSerializer: function(params) { return Qs.stringify(params, {arrayFormat: 'brackets'}) }, // `data`Is the data to be sent as the main body of the request // Applicable only to request method" PUT","POST"And " PATCH" // When not set`transformRequest`It must be one of the following types: // - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams // - Browser only: FormData, File, Blob // - Node only: Stream data: { firstName: 'Fred' }, // `timeout`Specifies the number of milliseconds before the request timeout. // If the request time exceeds'timeout',The request will be suspended. timeout: 1000, // `withCredentials`Indicates whether cross-site access control requests are available // should be made using credentials withCredentials: false, // default // `adapter'Allowing custom processing of requests makes testing easier. // Return to one promise And provide an effective response (see[response docs](#response-api)) adapter: function (config) { /* ... */ }, // `auth'Indicates that you should use HTTP Basic certification and provide credentials. // This will set up a`Authorization'Head, covering any existing`Authorization'Custom header, using`headers`Set up. auth: { username: 'janedoe', password: 's00pers3cret' }, // "responseType"Represents the data type that the server will respond to // Include 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream' responseType: 'json', // default //`xsrfCookieName`It is for use. xsrf The value of the token cookie Name xsrfCookieName: 'XSRF-TOKEN', // default // `xsrfHeaderName`Carry xsrf Token value http Name of head xsrfHeaderName: 'X-XSRF-TOKEN', // default // `onUploadProgress`Allow processing of uploaded progress events onUploadProgress: function (progressEvent) { // Use local progress Events do whatever you want to do }, // `onDownloadProgress`Allow processing of downloaded progress events onDownloadProgress: function (progressEvent) { // Do whatever you want with the native progress event }, // `maxContentLength`Define permissible http Maximum size of response content maxContentLength: 2000, // `validateStatus`Define whether to parse or reject a given promise // HTTP Response status code. If`validateStatus`Return`true`(Or set to`null` promise Will be resolved;Otherwise, promise Will be // Refuse. validateStatus: function (status) { return status >= 200 && status < 300; // default }, // `maxRedirects`Defined in node.js The maximum number of reorientations to follow. // If set to 0, redirection is not followed. maxRedirects: 5, // default // `httpAgent`and`httpsAgent`Used to define in node.js Separate execution http and https Custom proxies used when requesting. // Allow configuration similar`keepAlive`Options, // Not enabled by default. httpAgent: new http.Agent({ keepAlive: true }), httpsAgent: new https.Agent({ keepAlive: true }), // 'proxy'Define the host name and port of the proxy server // `auth`Express HTTP Basic auth It should be used to connect to the proxy and provide credentials. // This will set up a`Proxy-Authorization` header,Cover any use`headers`Set up the existing`Proxy-Authorization` custom headers. proxy: { host: '127.0.0.1', port: 9000, auth: : { username: 'mikeymike', password: 'rapunz3l' } }, // "cancelToken"Specifies a cancellation token that can be used to cancel requests // (see Cancellation section below for details) cancelToken: new CancelToken(function (cancel) { }) }
When using the then, you will receive the following response:
axios.get('/user/12345') .then(function(response) { console.log(response.data); console.log(response.status); console.log(response.statusText); console.log(response.headers); console.log(response.config); });
1.4. Configure default values
You can specify the default configuration values that will be applied to each request.
1.4.1, Global axios default
axios.defaults.baseURL = 'https://api.example.com'; axios.defaults.headers.common['Authorization'] = AUTH_TOKEN; axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
1.4.2. Default values for custom instances
//Set configuration defaults when creating instances var instance = axios.create({ baseURL: 'https://api.example.com' }); //Change default values after instance creation instance.defaults.headers.common ['Authorization'] = AUTH_TOKEN;
1.4.3, Configuration Priority Order
Configuration will be merged with priority. The order is the library default in lib / defaults.js, then the defaults attribute of the instance, and finally the config parameter of the request. The latter will take precedence over the former. Here is an example.
//Create instances using configuration defaults provided by Libraries //At this point, the timeout configuration value is`0`,This is the default value for the library var instance = axios.create(); //Override Library Timeout Default //Now all requests will wait 2 before the timeout.5 second instance.defaults.timeout = 2500; //Override the timeout of this request because it knows it takes a long time instance.get('/ longRequest',{ timeout: 5000 });
1.5. Interceptor
You can intercept requests or responses before they are processed by the then or catch.
//Add request interceptor axios.interceptors.request.use(function(config){ //Do something before sending a request return config; },function(error){ //Do something when requesting errors return Promise.reject(error); }); //Adding Response Interceptor axios.interceptors.response.use(function(response){ //Do something about response data return response; },function(error){ //Do something when requesting errors return Promise.reject(error); });
If you may need to delete the interceptor later.
var myInterceptor = axios.interceptors.request.use(function () {/*...*/}); axios.interceptors.request.eject(myInterceptor);
You can add the interceptor to a custom instance of axios.
var instance = axios.create(); instance.interceptors.request.use(function () {/*...*/});
1.6. Handling errors
axios.get('/ user / 12345') .catch(function(error){ if(error.response){ //The request was sent, but the server responded with status code //Fall to 2 xx Outside the scope console.log(error.response.data); console.log(error.response.status); console.log(error.response.headers); } else { //An error occurred while setting the request that triggered the error console.log('Error',error.message); }} console.log(error.config); });
You can use the validateStatus configuration option to define custom HTTP status code error ranges.
axios.get('/ user / 12345',{ validateStatus: function(status){ return status < 500; //Refusal only if status code is greater than or equal to 500 }} })
Cancellation
You can cancel the request with a cancel token.
The axios cancel token API is currently in phase 1, based on a cancelable promise proposal.
You can use the CancelToken.source factory to create a cancellation token, as follows:
var CancelToken = axios.CancelToken; var source = CancelToken.source(); axios.get('/user/12345', { cancelToken: source.token }).catch(function(thrown) { if (axios.isCancel(thrown)) { console.log('Request canceled', thrown.message); } else { // Handling errors } }); //Cancel requests (message parameters are optional) source.cancel('The operation was cancelled by the user.');
You can also create a cancellation token by passing the executor function to the CancelToken constructor:
var CancelToken = axios.CancelToken; var cancel; axios.get('/ user / 12345',{ cancelToken: new CancelToken(function executor(c){ //An actuator function receives a cancel function as a parameter cancel = c; }) }); // Cancellation request clear();
Note: You can cancel several requests with the same cancellation token.
1.8. Use the application/x-www-form-urlencoded format
By default, axios serializes JavaScript objects into JSON. To send data in the application / x-www-form-urlencoded format, you can use one of the following options.
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
1.8.1. Browser
In the browser, you can use the URLSearchParams API as follows:
var params = new URLSearchParams(); params.append('param1', 'value1'); params.append('param2', 'value2'); axios.post('/foo', params);
Note that URLSearchParams is not supported by all browsers, but a polyfill is available (to ensure a polyfill global environment).
Alternatively, you can use the qs library to encode the data:
var qs = require('qs'); axios.post('/foo', qs.stringify({ 'bar': 123 });
1.8.2, Node.js
In node.js, you can use the querystring module as follows:
var querystring = require('querystring'); axios.post('http://something.com/', querystring.stringify({ foo: 'bar' });
You can also use the qs library.
2.9,Promise
axios relies on native support for ES6 Promise implementation. If your environment does not support ES6 Promises, you can use polyfill.
1.10,TypeScript
axios includes TypeScript definitions.
import axios from 'axios';
axios.get('/user?ID=12345');
axios is largely inspired by Angular's $http service. Ultimately, axios strives to provide a separate $http-like service for use outside Angular.
Two, Lodash
Lodash is a JavaScript tool library with consistent interface, modularity and high performance. It encapsulates many processing functions for common data types, such as strings, arrays, objects, etc. Some of them are auxiliary functions which are recognized by the industry but have not yet been formulated by ECMAScript. At present, the number of installations of Lodash using npm every day is more than one million, which proves to some extent the robustness of the code, and it is worth trying in the project.
Official website: https://lodash.com/
Chinese Documents: http://www.css88.com/doc/lodash/
English help: https://lodash.com/docs/
GitHub: https://github.com/lodash/
2.1, Download
CDN Reference Address: https://cdn.jsdelivr.net/npm/lodash@4.17.4/lodash.min.js
2.2, installation
Browser:
<script src="lodash.js"></script> //or CDN <script scr="https://cdn.jsdelivr.net/npm/lodash@4.17.4/lodash.min.js"></script>
Using npm:
$ npm i -g npm
$ npm i --save lodash
Nodejs:
// Load the full build. var _ = require('lodash'); // Load the core build. var _ = require('lodash/core'); // Load the FP build for immutable auto-curried iteratee-first data-last methods. var fp = require('lodash/fp'); // Load method categories. var array = require('lodash/array'); var object = require('lodash/fp/object'); // Cherry-pick methods for smaller browserify/rollup/webpack bundles. var at = require('lodash/at'); var curryN = require('lodash/fp/curryN');
2.3. Module Composition
The auxiliary functions provided by Lodash are mainly divided into the following categories. For lists of functions and examples of usage, please see Lodash's official documents:
Array, for array types, such as filling data, finding elements, array slices, and so on
Collection, for array and object types, is partially applicable to strings, such as grouping, lookup, filtering, and so on.
Function, for function types, such as throttling, latency, caching, setting hooks, etc.
Lang, generally applicable to all types, is often used to perform type judgment and type conversion
Math, for numerical types, is often used to perform mathematical operations
Number, suitable for generating random numbers, comparing the relationship between numerical values and numerical intervals
Object, which is suitable for object types, is often used for object creation, extension, type conversion, retrieval, collection and other operations.
Seq, often used to create chain calls, improves execution performance (lazy computing)
String, for string types
lodash/fp module provides a more functional programming approach. Its internal functions are packaged and have the characteristics of immutable, auto-curried, iteratee-first and data-last.
2.4. Examples of Lodash Quick Start
2.4.1. N cycles
// 1. Basic for loop. for(var i = 0; i < 5; i++) { // ... } // 2. Using Array's join and split methods Array.apply(null, Array(5)).forEach(function(){ // ... }); // Lodash _.times(5, function(){ // ... });
for statement is the best choice to execute a loop, Array.apply can also simulate a loop, but in the use of the above code scenario,. times() solution is more concise and easy to understand.
Example:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Lodash</title> </head> <body> <div id="vm"> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script src="../js/lodash/lodash.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var vm = new Vue({ el: "#vm", data: { msg: "" }, methods: { } }); var log = function(str) { console.log(str); } log(_.times(5)); log(_.times(5, String)); log(_.times(5, _.constant(0))); log(_.times(5, _.constant(true))); var a5=_.times(5, function(v) { return v+10; }) log(a5); </script> </body> </html>
Result:
2.4.2. Deep Search Attribute Values
// Fetch the name of the first pet from each owner var ownerArr = [{ "owner": "Colin", "pets": [{"name":"dog1"}, {"name": "dog2"}] }, { "owner": "John", "pets": [{"name":"dog3"}, {"name": "dog4"}] }]; // Array's map method. ownerArr.map(function(owner){ return owner.pets[0].name; }); // Lodash _.map(ownerArr, 'pets[0].name');
The. Map method is an improvement of the native map method, which simplifies a lot of redundant code by using pets[0].name string to value nested data. It is very similar to using jQuery to select DOM node UL > Li > a, which has a long-lost cordiality for front-end developers.
Example:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Lodash</title> </head> <body> <script src="../js/lodash/lodash.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var log = function(str) { if(typeof str == "object") { console.log(JSON.stringify(str)); } console.log(str); } var arr = [{ "owner": "Colin", "pets": [{ "name": "dog1" }, { "name": "dog2" }] }, { "owner": "John", "pets": [{ "name": "dog3" }, { "name": "dog4" }] }]; log(_.map(arr,"pets")); log(_.map(arr,"owner")); log(_.map(arr,"pets[1].name")); log(_.map(arr,o=>o.pets[1].name+":)")); </script> </body> </html>
Result:
2.4.3. Personalized Array
// Array's map method. Array.apply(null, Array(6)).map(function(item, index){ return "ball_" + index; }); // Lodash _.times(6, _.uniqueId.bind(null, 'ball_')); // Lodash _.times(6, _.partial(_.uniqueId, 'ball_')); // eg. [ball_0, ball_1, ball_2, ball_3, ball_4, ball_5]
In the above code, we want to create an array with different initial values and 6 lengths, where the. uniqueId method is used to generate unique identifiers (incremental numbers that remain unique during the running of the program) and the partial method is used to encapsulate the bind.
Example:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Lodash</title> </head> <body> <script src="../js/lodash/lodash.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var log = function(str) { if(typeof str == "object") { console.log(JSON.stringify(str)); } console.log(str); } //Generate Unique Number log(_.uniqueId()); log(_.uniqueId("gdnf_")); //Encapsulation function function greet(greeting,name){ return greeting +" " +name; } log(greet("hello","tom")); var sayhello=_.partial(greet,'hello'); var sayhi=_.partial(greet,'hi'); log(sayhello('mark')); log(sayhi('rose')); //comprehensive var array=_.times(5,_.partial(_.uniqueId,'ball_')); log(array); </script> </body> </html>
Result:
2.4.4. Deep copy
var objA = { "name": "colin" } // Normal method? Too long. See Stackoverflow for solution: // http://stackoverflow.com/questions/4459928/how-to-deep-clone-in-javascript // Lodash var objB = _.cloneDeep(objA); objB === objA // false
JavaScript does not directly provide deep copy functions, but we can use other functions to simulate, such as JSON. parse (JSON. stringify (objectToClone), but this method requires that the attribute value in the object cannot be a function. The. cloneDeep function in Lodash encapsulates the logic of deep copies and is more concise to use.
Example:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Lodash</title> </head> <body> <script src="../js/lodash/lodash.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var log = function(str) { if(typeof str == "object") { console.log(JSON.stringify(str)); } console.log(str); } var obj0={address:"Zhuhai, China"}; var obj1 = { id: 1, name: "rose", position:obj0 }; log("Quote"); //Quote var obj2=obj1; log(obj2==obj1); log("shallow copy"); //shallow copy var obj3=_.clone(obj1); log(obj3==obj1); log(obj3===obj1); log(obj3.position===obj1.position); log("deep copy"); //deep copy var obj4=_.cloneDeep(obj1); log(obj4==obj1); log(obj4===obj1); log(obj4.position===obj1.position); </script> </body> </html>
Result:
2.4.5. Random Numbers
// Naive utility method function getRandomNumber(min, max){ return Math.floor(Math.random() * (max - min + 1)) + min; } getRandomNumber(15, 20); // Lodash _.random(15, 20);
Lodash's random number generating function is closer to the actual development. ECMAScript's random number generating function is the necessary interface at the bottom, both of which are indispensable. In addition, using. random(15, 20, true) can also generate random floating point numbers between 15 and 20.
Example:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Lodash</title> </head> <body> <script src="../js/lodash/lodash.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var log = function(str) { if(typeof str == "object") { console.log(JSON.stringify(str)); } console.log(str); } var obj0={address:"Zhuhai, China"}; var obj1 = { id: 1, name: "rose", position:obj0 }; var arr=_.times(10,function(){ return _.random(1,100); }); log(arr); </script> </body> </html>
Result:
2.4.6. Object Extension
// Adding extend function to Object.prototype Object.prototype.extend = function(obj) { for (var i in obj) { if (obj.hasOwnProperty(i)) { this[i] = obj[i]; } } }; var objA = {"name": "colin", "car": "suzuki"}; var objB = {"name": "james", "age": 17}; objA.extend(objB); objA; // {"name": "james", "age": 17, "car": "suzuki"}; // Lodash _.assign(objA, objB);
_. assign is a shallow copy, which is consistent with the new Ojbect.assign function in ES6 (Object.assign is preferred).
Example:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Lodash</title> </head> <body> <script src="../js/lodash/lodash.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var log = function(str) { if(typeof str == "object") { console.log(JSON.stringify(str)); } console.log(str); } var obj0 = { address: "Zhuhai, China" }; var obj1 = { id: 1, name: "rose", position: obj0 }; var x = { a: 1, b: 2, c: 3 }; var y = { b: 5, c: 6, d: 7 }; //use y extend x _.assign(x,y); log(x); //x Has been revised. log(y); </script> </body> </html>
Result:
2.4.7. Screening attributes
// Naive method: Remove an array of keys from object Object.prototype.remove = function(arr) { var that = this; arr.forEach(function(key){ delete(that[key]); }); }; var objA = {"name": "colin", "car": "suzuki", "age": 17}; objA.remove(['car', 'age']); objA; // {"name": "colin"} // Lodash objA = _.omit(objA, ['car', 'age']); // => {"name": "colin"} objA = _.omit(objA, 'car'); // => {"name": "colin", "age": 17}; objA = _.omit(objA, _.isNumber); // => {"name": "colin"};
In most cases, Lodash provides auxiliary functions that are closer to development requirements than native functions. In the above code, developers can use arrays, strings and functions to filter the attributes of objects, and eventually return a new object, which will not affect the old object when filtering is performed in the middle.
// Naive method: Returning a new object with selected properties Object.prototype.pick = function(arr) { var _this = this; var obj = {}; arr.forEach(function(key){ obj[key] = _this[key]; }); return obj; }; var objA = {"name": "colin", "car": "suzuki", "age": 17}; var objB = objA.pick(['car', 'age']); // {"car": "suzuki", "age": 17} // Lodash var objB = _.pick(objA, ['car', 'age']); // {"car": "suzuki", "age": 17}
Picking is the opposite of. omit, which is used to select attributes from other objects to generate new objects.
Example:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Lodash</title> </head> <body> <script src="../js/lodash/lodash.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var log = function(str) { if(typeof str == "object") { console.log(JSON.stringify(str)); } console.log(str); } var obj0 = { address: "Zhuhai, China" }; var obj1 = { id: 1, name: "rose", position: obj0 }; var student = { name: "Zhang San", age: 18, address: "Hongkong, China" }; //Delete the property address without modifying the original array var obj1 = _.omit(student, "address"); log(obj1); var obj2 = _.omit(student, ['age','name']); log(obj2); </script> </body> </html>
Result:
2.4.8. Random Elements
var luckyDraw = ["Colin", "John", "James", "Lily", "Mary"]; function pickRandomPerson(luckyDraw){ var index = Math.floor(Math.random() * (luckyDraw.length -1)); return luckyDraw[index]; } pickRandomPerson(luckyDraw); // John // Lodash _.sample(luckyDraw); // Colin // Lodash - Getting 2 random item _.sample(luckyDraw, 2); // ['John','Lily']
sample supports random selection of multiple elements and returning new arrays.
Example:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Lodash</title> </head> <body> <script src="../js/lodash/lodash.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var log = function(str) { if(typeof str == "object") { console.log(JSON.stringify(str)); } console.log(str); } var luckyDraw = ["Colin", "John", "James", "Lily", "Mary"]; //Get one at random log(_.sample(luckyDraw)); //Random access to multiple log(_.sampleSize(luckyDraw,2)); </script> </body> </html>
Result:
2.4.9. Error handling for JSON.parse
// Using try-catch to handle the JSON.parse error function parse(str){ try { return JSON.parse(str); } catch(e) { return false; } } // With Lodash function parseLodash(str){ return _.attempt(JSON.parse.bind(null, str)); } parse('a'); // => false parseLodash('a'); // => Return an error object parse('{"name": "colin"}'); // => Return {"name": "colin"} parseLodash('{"name": "colin"}'); // => Return {"name": "colin"}
If you use JSON.parse without preset error handling, then it is likely to become a time bomb, we should not default to receive JSON objects are valid. Try-catch is the most common way to handle errors. If Lodash is in a project, try-catch can be replaced by. attmpt, which returns an Error object when parsing JSON errors.
With the popularity of ES6, Lodash's functions will be more or less replaced by native functions, so further screening is needed when using it. It is suggested that native functions be preferred.
2.5, More Functions
1) _.map(collection, [iteratee=_.identity], [thisArg])
Role: Create an array of results for each element in an iteratee-processed collection. The iteratee passes in three parameters: (value, index|key, collection).
Aliases:. collect
Parametric 1: The set that needs to be traversed can be an array, an object, or a string.
Parametric 2: An iterator, which can be a function, an object, or a string.
Parametric 3: The object bound by this in the iterator.
Return value (Array): A new array after mapping.
Example:
1 function timesThree(n) { 2 return n * 3; 3 } 4 5 _.map([1, 2], timesThree); 6 // => [3, 6] 7 8 _.map({ 'a': 1, 'b': 2 }, timesThree); 9 // => [3, 6] (iteration order is not guaranteed) 10 11 var users = [ 12 { 'user': 'barney' }, 13 { 'user': 'fred' } 14 ]; 15 16 // using the `_.property` callback shorthand 17 _.map(users, 'user'); 18 // => ['barney', 'fred']
2) _.chunk(array, [size=1])
Function: Divide the array into blocks of several size s and form a new array. If the array cannot be divided into all equal-length blocks, the last remaining elements will form a block.
Parametric 1: Arrays that need to be processed.
Parametric 2: Length of each block.
Return value (Array): Returns a new array containing a splitting block array (equivalent to a two-dimensional array).
Example:
1 _.chunk(['a', 'b', 'c', 'd'], 2); 2 // => [['a', 'b'], ['c', 'd']] 3 4 _.chunk(['a', 'b', 'c', 'd'], 3); 5 // => [['a', 'b', 'c'], ['d']]
3) _.compact(array)
Role: Create a new array and include all non-pseudo-value elements in the original array. For example, false, null, 0, ""","undefined"and NaN are all"false values".
Parameter: An array that needs to be filtered.
Array: An array after filtering false values.
Example:
1 _.compact([0, 1, false, 2, '', 3]); 2 // => [1, 2, 3]
4) _.difference(array, [values])
Role: Create a differentiated array, excluding the array provided using the SameValueZero method.
Parametric 1: Array to be processed.
Parametric 2): Values that need to be excluded from the array.
Return value (Array): filtered array.
Example:
1 _.difference([1, 2, 3], [4, 2]); 2 // => [1, 3] 3 _.difference([1, '2', 3], [4, 2]); 4 // => [1, "2", 3]
5) _.drop(array, [n=1])
Function: Remove the first n elements from the array and return the rest.
Parametric 1: An array to be manipulated.
Parametric 2: Number of elements removed.
Return value (Array): The remainder of the array.
Example:
1 _.drop([1, 2, 3]); 2 // => [2, 3] The default is to start with 1 3 4 _.drop([1, 2, 3], 2); 5 // => [3] 6 7 _.drop([1, 2, 3], 5); 8 // => [] 9 10 _.drop([1, 2, 3], 0); 11 // => [1, 2, 3]
6)_.dropRight(array, [n=1])
Action: Remove n elements from the tail of the array and return the rest.
Parametric 1: Arrays that need to be processed.
Parametric 2: Number of elements removed.
Return value (Array): The remainder of the array.
Example:
1 _.dropRight([1, 2, 3]); 2 // => [1, 2] 3 4 _.dropRight([1, 2, 3], 2); 5 // => [1] 6 7 _.dropRight([1, 2, 3], 5); 8 // => [] 9 10 _.dropRight([1, 2, 3], 0); 11 // => [1, 2, 3]
7)_.dropRightWhile(array, [predicate=_.identity], [thisArg])
Function: From the end of the query (right) array, the first element that does not satisfy the predicate condition begins to intercept the array.
Parametric 1: An array that needs to be queried.
Parametric 2): An iterator, which can be a function, an object, or a string.
Parametric 3): The value corresponding to the predicate attribute.
Array: An array after intercepting elements.
Example:
1 _.dropRightWhile([1, 2, 3], function(n) { 2 return n > 1; 3 }); 4 // => [1] 5 6 var users = [ 7 { 'user': 'barney', 'active': true }, 8 { 'user': 'fred', 'active': false }, 9 { 'user': 'pebbles', 'active': false } 10 ]; 11 12 // using the `_.matches` callback shorthand 13 _.pluck(_.dropRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user'); 14 // => ['barney', 'fred'] 15 16 // using the `_.matchesProperty` callback shorthand 17 _.pluck(_.dropRightWhile(users, 'active', false), 'user'); 18 // => ['barney'] 19 20 // using the `_.property` callback shorthand 21 _.pluck(_.dropRightWhile(users, 'active'), 'user'); 22 // => ['barney', 'fred', 'pebbles']
8)_.pluck(collection, path)
Function: Extract the attribute values of path s specified in the set.
Parametric 1): Array to be extracted.
Parametric 2: The path corresponding to the attribute to be extracted.
Array: An array of extracted attribute values.
Example:
1 var users = [ 2 { 'user': 'barney', 'age': 36 }, 3 { 'user': 'fred', 'age': 40 } 4 ]; 5 6 _.pluck(users, 'user'); 7 // => ['barney', 'fred'] 8 9 var userIndex = _.indexBy(users, 'user'); 10 _.pluck(userIndex, 'age'); 11 // => [36, 40] (iteration order is not guaranteed)
9)_.fill(array, value, [start=0], [end=array.length])
Function: Fill (i.e. replace) array with value, starting at the start position and ending at the end position (but excluding the end position).
Parametric 1): Array to be filled.
Parametric 2: Fill in the value of the array element.
Parametric 3: Starting position (including).
Parametric 4: End position (excluded).
Array: Filled array.
Example:
1 var array = [1, 2, 3]; 2 3 _.fill(array, 'a'); 4 console.log(array); 5 // => ['a', 'a', 'a'] 6 7 _.fill(Array(3), 2); 8 // => [2, 2, 2] 9 10 _.fill([4, 6, 8], '*', 1, 2); 11 // => [4, '*', 8]
10)_.findIndex(array, [predicate=_.identity], [thisArg])
Function: This method is similar to. find, except that it returns an index of the first element that meets the predicate criteria, rather than the element itself.
Parametric 1): Array to be searched.
Parametric 2: An iterator, which can be a function, an object, or a string.
Parametric 3): The value corresponding to the predicate attribute.
Number: The index value of an element that meets the query criteria, returns -1 if it is not found.
Example:
1 var users = [ 2 { 'user': 'barney', 'active': false }, 3 { 'user': 'fred', 'active': false }, 4 { 'user': 'pebbles', 'active': true } 5 ]; 6 7 _.findIndex(users, function(chr) { 8 return chr.user == 'barney'; 9 }); 10 // => 0 11 12 // using the `_.matches` callback shorthand 13 _.findIndex(users, { 'user': 'fred', 'active': false }); 14 // => 1 15 16 // using the `_.matchesProperty` callback shorthand 17 _.findIndex(users, 'active', false); 18 // => 0 19 20 // using the `_.property` callback shorthand 21 _.findIndex(users, 'active'); 22 // => 2
11)_.find(collection, [predicate=_.identity], [thisArg])
Role: Traverse through the elements in the collection and return the elements that were first checked as true values by predicate. Preicate passes in three elements: (value, index|key, collection).
Parametric 1): The collection to be retrieved can be an array, an object, or a string.
Parametric 2: An iterator, which can be a function, an object, or a string.
Parametric 3: The object bound by this in the iterator.
Return value: Match element, otherwise return undefined.
Example:
1 var users = [ 2 { 'user': 'barney', 'age': 36, 'active': true }, 3 { 'user': 'fred', 'age': 40, 'active': false }, 4 { 'user': 'pebbles', 'age': 1, 'active': true } 5 ]; 6 7 _.find(users, function(o) { return o.age < 40; }); 8 // => 'barney' 9 10 // Used `_.matches` Callback results 11 _.find(users, { 'age': 1, 'active': true }); 12 // => 'pebbles' 13 14 // Used `_.matchesProperty` Callback results 15 _.find(users, ['active', false]); 16 // => 'fred' 17 18 // Used `_.property` Callback results 19 _.find(users, 'active'); 20 // => 'barney'
12)_.forEach(collection, [iteratee=_.identity], [thisArg])
Role: By calling iteratee to traverse elements in a collection, iteratee passes in three parameters: (value, index|key, collection). If it explicitly returns false, iterate exits early.
Parametric 1): The set that needs to be traversed can be an array, an object, or a string.
Parametric 2: Iterator, only function.
Parametric 3: The object bound by this in the iterator.
Return value: the set after traversal.
Example:
1 _([1, 2]).forEach(function(value) { 2 console.log(value); 3 }); 4 // => output `1` and `2` 5 6 _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { 7 console.log(key); 8 }); 9 // => output 'a' and 'b' (The order of traversal is not guaranteed)
13)_.reduce(collection, [iteratee=_.identity], [accumulator], [thisArg])
Role: Traverse through each element in the collection through iteratee. The value returned each time is used as the next iteratee. If accumulator is not provided, the first element in the collection as accumulator. iterate passes in four parameters: (accumulator, value, index|key, collection).
Parametric 1): The set that needs to be traversed can be an array, an object, or a string.
Parametric 2: Iterator, only function.
Parametric 3: Initial value of accumulator.
Parametric 4: The object bound by this in the iterator.
Return value: cumulative value.
Example:
1 _.reduce([1, 2], function(total, n) { 2 return total + n; 3 }); 4 // => 3 5 6 _.reduce({ 'a': 1, 'b': 2 }, function(result, n, key) { 7 result[key] = n * 3; 8 return result; 9 }, {}); 10 // => { 'a': 3, 'b': 6 } (iteration order is not guaranteed)
14)_.some(collection, [predicate=_.identity], [thisArg])
Function: Check whether the elements in the set have any truth value by predicate. As long as predicate returns one truth value, the traversal stops and returns true. predicate passes in three parameters: (value, index|key, collection).
Parametric 1): The set that needs to be traversed can be an array, an object, or a string.
Parametric 2: An iterator, which can be a function, an object, or a string.
Parametric 3: The object bound by this in the iterator.
Return value: If any element is true by predicate check, return true, otherwise return false.
Example:
1 _.some([null, 0, 'yes', false], Boolean); 2 // => true 3 4 var users = [ 5 { 'user': 'barney', 'active': true }, 6 { 'user': 'fred', 'active': false } 7 ]; 8 9 // using the `_.matches` callback shorthand 10 _.some(users, { 'user': 'barney', 'active': false }); 11 // => false 12 13 // using the `_.matchesProperty` callback shorthand 14 _.some(users, 'active', false); 15 // => true 16 17 // using the `_.property` callback shorthand 18 _.some(users, 'active'); 19 // => true
15)_.chain(value)
Role: Create a lodash object containing value to open the built-in method chain. The method chain acts on methods that return arrays, collections, or functions, and methods can be chained.
Parameter: The value of the lodash object that needs to be wrapped.
Return value: an instance of a new lodash object.
Example:
1 var users = [ 2 { 'user': 'barney', 'age': 36 }, 3 { 'user': 'fred', 'age': 40 }, 4 { 'user': 'pebbles', 'age': 1 } 5 ]; 6 7 var youngest = _.chain(users) 8 .sortBy('age') 9 .map(function(chr) { 10 return chr.user + ' is ' + chr.age; 11 }) 12 .first() 13 .value(); 14 // => 'pebbles is 1'
Three. Homework
3.1. Use axios+vue2 to implement Mini Task Management, MicTodo. Requirements and steps are as follows:
- Define background services. Note that cross-domain services can also be simplified to same-domain services (simulate background data)
- Implement the functions of adding, modifying, deleting and querying tasks
- Only these attributes (number id, name, state) are needed in the task, and time is better, of course.
- Using Lodash to complete the search function, you can specify the columns to display
3.2. Find five methods about set operation in Loadsh. The test passes and can't be the same as the example in class.
IV. Example Download
https://git.coding.net/zhangguo5/vue2.git