一、axios

Vue更新到2.0之后宣告不再对vue-resource更新,推荐使用axios,axios是一个用于客户端与服务器通信的组件,axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端javaScript工具。通俗来说可以实现客户端请求服务器端提供的服务获得数据。

源码与帮助:https://github.com/axios/axios

服务器端跨域支持请查看:http://www.cnblogs.com/best/p/6196202.html#_label2

1.1、特点

  • 从浏览器中创建 XMLHttpRequest
  • 从 node.js 发出 http 请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求和响应数据
  • 取消请求
  • 自动转换JSON数据
  • 客户端支持防止 CSRF/XSRF

1.2、浏览器兼容性

1.3、依赖办法

  1. $ npm install axios
  2. $ cnpm install axios //taobao
  3. $ bower install axios
  4. 或者使用cdn
  5. <script src="https://unpkg.com/axios/dist/axios.min.js"></script>

浏览器可以引入js文件

1.4、快速入门

1.4.0、服务器端

控制器:

  1. package com.zhangguo.springmvc08.controller;
  2.  
  3. import com.zhangguo.springmvc08.entity.User;
  4. import com.zhangguo.springmvc08.service.UserService;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.web.bind.annotation.*;
  7.  
  8. import javax.servlet.http.HttpServletRequest;
  9. import javax.servlet.http.HttpServletResponse;
  10. import java.util.List;
  11.  
  12. @RestController
  13. @RequestMapping(path = "/emps")
  14. public class EmpController extends BaseController {
  15.  
  16. @Autowired
  17. UserService userService;
  18.  
  19. @RequestMapping(path = "")
  20. public AjaxState getAllEmps(HttpServletRequest request, HttpServletResponse response) {
  21. List<User> users=userService.queryAllUsers();
  22. boolean result=users!=null;
  23. return new AjaxState(result?"success":"error",users,result?"获得数据成功!":"获得数据失败!");
  24. }
  25.  
  26. @RequestMapping(path = "/{id}", method = RequestMethod.GET)
  27. public AjaxState getEmpById(@PathVariable int id) {
  28. User user=userService.getUserById(id);
  29. boolean result=user!=null;
  30. return new AjaxState(result?"success":"error",user,result?"获得数据成功!":"获得数据失败!");
  31. }
  32.  
  33. @RequestMapping(path = "/getEmpById", method = RequestMethod.GET)
  34. public AjaxState getEmpById(HttpServletRequest request) {
  35. int id=Integer.parseInt(request.getParameter("id"));
  36. User user=userService.getUserById(id);
  37. boolean result=user!=null;
  38. return new AjaxState(result?"success":"error",user,result?"获得数据成功!":"获得数据失败!");
  39. }
  40.  
  41. @RequestMapping(path = "", method = RequestMethod.POST)
  42. public AjaxState addEmp(@RequestBody User user) {
  43. boolean result=userService.addUser(user);
  44. return new AjaxState(result?"success":"error",user,result?"添加成功!":"添加失败");
  45. }
  46.  
  47. @RequestMapping(path = "", method = RequestMethod.PUT)
  48. public AjaxState updateEmp(@RequestBody User user) {
  49. boolean result=userService.editUser(user);
  50. return new AjaxState(result?"success":"error",user,result?"修改成功!":"修改失败");
  51. }
  52.  
  53. @RequestMapping(path = "/{id}", method = RequestMethod.DELETE)
  54. public AjaxState deleteEmpById(@PathVariable int id) {
  55. Boolean result=userService.deleteUser(id);
  56. return new AjaxState(result?"success":"error",id,result?"删除成功!":"删除失败");
  57. }
  58.  
  59. }
  60.  
  61. class AjaxState{
  62. public String state;
  63. public Object data;
  64. public String message;
  65.  
  66. public AjaxState(String state, Object data, String message) {
  67. this.state = state;
  68. this.data = data;
  69. this.message = message;
  70. }
  71.  
  72. public AjaxState(){}
  73. }

跨域设置(任选一种):

方法1:Servlet,MVC都可以,Web.xml

  1. <filter>
  2. <filter-name>CORS</filter-name>
  3. <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
  4. <init-param>
  5. <param-name>cors.allowOrigin</param-name>
  6. <param-value>http://127.0.0.1:8020</param-value>
  7. </init-param>
  8. <init-param>
  9. <param-name>cors.supportedMethods</param-name>
  10. <param-value>POST,GET,OPTIONS,DELETE,PUT</param-value>
  11. </init-param>
  12. <init-param>
  13. <param-name>cors.supportedHeaders</param-name>
  14. <param-value>Content-Type,Accept,Origin,XRequestedWith,ContentType,LastModified</param-value>
  15. </init-param>
  16. <init-param>
  17. <param-name>cors.exposedHeaders</param-name>
  18. <param-value>SetCookie</param-value>
  19. </init-param>
  20. <init-param>
  21. <param-name>cors.supportsCredentials</param-name>
  22. <param-value>true</param-value>
  23. </init-param>
  24. </filter>
  25.  
  26. <filter-mapping>
  27. <filter-name>CORS</filter-name>
  28. <url-pattern>/*</url-pattern>
  29. </filter-mapping>

方法2:Spring MVC,修改Spring 配置文件,低Spring版本不支持

  1. <mvc:cors>
  2. <mvc:mapping path="/**"
  3. allowed-origins="http://127.0.0.1:8020"
  4. allowed-methods="POST,GET, OPTIONS,DELETE,PUT"
  5. allowed-headers="Content-Type,ContentType,Access-Control-Allow-Headers, Authorization, X-Requested-With"
  6. allow-credentials="true"/>
  7. </mvc:cors>

1.4.1、发送Get请求

  1. //向具有指定ID的用户发出请求
  2. axios.get('/user?ID=123')
  3. .then(function (response) {
  4. console.log(response);
  5. })
  6. .catch(function (error) {
  7.   console.log(error);
  8. });
  9.  
  10. //也可以通过 params 对象传递参数
  11. axios.get('/user', {
  12. params: {
  13.   ID: 12345
  14. }
  15. })
  16. .then(function (response) {
  17.   console.log(response);
  18. })
  19. .catch(function (error) {
  20.   console.log(error);
  21. });

示例:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>axios</title>
  6. </head>
  7. <body>
  8. <div id="vm">
  9. <button type="button" @click="get">Get请求</button>
  10. <button type="button" @click="getParam">Get请求带参数</button>
  11. <h3>{{msg}}</h3>
  12. </div>
  13. <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
  14. <script src="../js/axios/axios.min.js" type="text/javascript" charset="utf-8"></script>
  15. <script type="text/javascript">
  16. var vm = new Vue({
  17. el: "#vm",
  18. data: {
  19. msg: ""
  20. },
  21. methods: {
  22. get: function() {
  23. var that = this;
  24. axios.get("http://localhost:8080/mvc08/emps").then(function(response) {
  25. console.log(response);
  26. //this.msg=JSON.stringify(response.data); //错误this指向window
  27. vm.msg = JSON.stringify(response.data);
  28. that.msg = JSON.stringify(response.data);
  29. }).catch(function(error) {
  30. console.log(error);
  31. })
  32. },
  33. getParam: function() {
  34. axios.get("http://localhost:8080/mvc08/emps/getEmpById", {
  35. params: {
  36. id: 1
  37. }
  38. }).then(function(response) {
  39. vm.msg = JSON.stringify(response.data);
  40. }).catch(function(error) {
  41. console.log(error);
  42. })
  43. }
  44. }
  45. });
  46. </script>
  47. </body>
  48. </html>

结果:

get请求

带参数:

默认的content-type为:application/json;charset=UTF-8

1.4.2、发送Post请求

  1. axios.post('/user', {
  2. firstName: 'Fred',
  3. lastName: 'Flintstone'
  4. })
  5. .then(function (response) {
  6. console.log(response);
  7. })
  8. .catch(function (error) {
  9. console.log(error);
  10. });

示例(添加一个用户):

  1. <!DOCTYPE html>
  2. <html>
  3.  
  4. <head>
  5. <meta charset="UTF-8">
  6. <title>axios</title>
  7. </head>
  8.  
  9. <body>
  10. <div id="vm">
  11. <button type="button" @click="get">Get请求</button>
  12. <button type="button" @click="getParam">Get请求带参数</button>
  13. <button type="button" @click="post">Post请求带参数</button>
  14. <h3>{{msg}}</h3>
  15. </div>
  16. <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
  17. <script src="../js/axios/axios.min.js" type="text/javascript" charset="utf-8"></script>
  18. <script type="text/javascript">
  19. var vm = new Vue({
  20. el: "#vm",
  21. data: {
  22. msg: ""
  23. },
  24. methods: {
  25. get: function() { //get请求
  26. var that = this;
  27. axios.get("http://localhost:8080/mvc08/emps").then(function(response) {
  28. console.log(response);
  29. //this.msg=JSON.stringify(response.data); //错误this指向window
  30. vm.msg = JSON.stringify(response.data);
  31. that.msg = JSON.stringify(response.data);
  32. }).catch(function(error) {
  33. console.log(error);
  34. })
  35. },
  36. getParam: function() { //带参数的get
  37. axios.get("http://localhost:8080/mvc08/emps/getEmpById", {
  38. params: {
  39. id: 1
  40. }
  41. }).then(function(response) {
  42. vm.msg = JSON.stringify(response.data);
  43. console.log(response);
  44. }).catch(function(error) {
  45. console.log(error);
  46. })
  47. },
  48. post: function() { //post
  49. var user = {
  50. "id": 1,
  51. "name": "张一三",
  52. "birthday": "1998-09-08",
  53. "address": "中国北京",
  54. "phone": "18989891122"
  55. };
  56.  
  57. axios
  58. .post("http://localhost:8080/mvc08/emps", user)
  59. .then(function(response) {
  60. vm.msg=response.data.data;
  61. console.log(response);
  62. })
  63. .catch(function(error){
  64. console.log(error);
  65. });
  66. }
  67. }
  68. });
  69. </script>
  70. </body>
  71.  
  72. </html>

结果:

1.4.3、发送多个并发请求

  1. function getUserAccount() {
  2. return axios.get('/user/12345');
  3. }
  4.  
  5. function getUserPermissions() {
  6. return axios.get('/user/12345/permissions');
  7. }
  8.  
  9. axios.all([getUserAccount(), getUserPermissions()])
  10. .then(axios.spread(function (acct, perms) {
  11. //两个请求现已完成
  12. }));

示例(同时获得编号为1与编号为2的学生,通过两个请求完成):

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>axios</title>
  6. </head>
  7. <body>
  8. <div id="vm">
  9. <button type="button" @click="all">all请求(并发请求)</button>
  10. <h3>{{msg}}</h3>
  11. </div>
  12. <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
  13. <script src="../js/axios/axios.min.js" type="text/javascript" charset="utf-8"></script>
  14. <script type="text/javascript">
  15. var vm = new Vue({
  16. el: "#vm",
  17. data: {
  18. msg: ""
  19. },
  20. methods: {
  21. all:function(){
  22. //获得用户对象1
  23. var getUser1=function(){
  24. return axios.get("http://localhost:8080/mvc08/emps/1");
  25. };
  26. //获得用户对象2
  27. var getUser2=function(){
  28. return axios.get("http://localhost:8080/mvc08/emps/2");
  29. };
  30. //并发请求处理结果
  31. axios.all([getUser1(),getUser2()])
  32. .then(axios.spread(function(response1,response2){
  33. var result="";
  34. result+=JSON.stringify(response1.data.data);
  35. result+=JSON.stringify(response2.data.data);
  36. vm.msg=result;
  37. }))
  38. .catch(function(error){
  39. console.log(error);
  40. });
  41. }
  42. }
  43. });
  44. </script>
  45. </body>
  46. </html>

结果:

1.4.4、发送Put请求

示例(修改编号为1的用户信息):

  1. <!DOCTYPE html>
  2. <html>
  3.  
  4. <head>
  5. <meta charset="UTF-8">
  6. <title>axios</title>
  7. </head>
  8.  
  9. <body>
  10. <div id="vm">
  11. <button type="button" @click="all">all请求(并发请求)</button>
  12. <button type="button" @click="put">put请求(修改数据)</button>
  13. <h3>{{msg}}</h3>
  14. </div>
  15. <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
  16. <script src="../js/axios/axios.min.js" type="text/javascript" charset="utf-8"></script>
  17. <script type="text/javascript">
  18. var vm = new Vue({
  19. el: "#vm",
  20. data: {
  21. msg: ""
  22. },
  23. methods: {
  24. all: function() {
  25. //获得用户对象1
  26. var getUser1 = function() {
  27. return axios({
  28. url:"http://localhost:8080/mvc08/emps/1",
  29. method:"get"
  30. });
  31. };
  32. //获得用户对象2
  33. var getUser2 = function() {
  34. return axios.get("http://localhost:8080/mvc08/emps/2");
  35. };
  36. //并发请求处理结果
  37. axios.all([getUser1(), getUser2()])
  38. .then(axios.spread(function(response1, response2) {
  39. var result = "";
  40. result += JSON.stringify(response1.data.data);
  41. result += JSON.stringify(response2.data.data);
  42. vm.msg = result;
  43. }))
  44. .catch(function(error) {
  45. console.log(error);
  46. });
  47. },
  48. put: function() {
  49. var user = {
  50. "id": 1,
  51. "name": "张学霸",
  52. "birthday": "1988-09-08",
  53. "address": "中国珠海",
  54. "phone": "13223456786"
  55. };
  56. axios.put("http://localhost:8080/mvc08/emps",user)
  57. .then(r=>vm.msg=r.data.data)
  58. .catch(e=>console.log(e));
  59. }
  60. }
  61. });
  62. </script>
  63. </body>
  64.  
  65. </html>

结果:

1.4.5、发送Delete请求

示例(删除编号为2的用户):

  1. <!DOCTYPE html>
  2. <html>
  3.  
  4. <head>
  5. <meta charset="UTF-8">
  6. <title>axios</title>
  7. </head>
  8.  
  9. <body>
  10. <div id="vm">
  11. <button type="button" @click="all">all请求(并发请求)</button>
  12. <button type="button" @click="remove">delete请求(删除数据)</button>
  13. <h3>{{msg}}</h3>
  14. </div>
  15. <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
  16. <script src="../js/axios/axios.min.js" type="text/javascript" charset="utf-8"></script>
  17. <script type="text/javascript">
  18. var vm = new Vue({
  19. el: "#vm",
  20. data: {
  21. msg: ""
  22. },
  23. methods: {
  24. all: function() {
  25. //获得用户对象1
  26. var getUser1 = function() {
  27. return axios({
  28. url:"http://localhost:8080/mvc08/emps/1",
  29. method:"get"
  30. });
  31. };
  32. //获得用户对象2
  33. var getUser2 = function() {
  34. return axios.get("http://localhost:8080/mvc08/emps/2");
  35. };
  36. //并发请求处理结果
  37. axios.all([getUser1(), getUser2()])
  38. .then(axios.spread(function(response1, response2) {
  39. var result = "";
  40. result += JSON.stringify(response1.data.data);
  41. result += JSON.stringify(response2.data.data);
  42. vm.msg = result;
  43. }))
  44. .catch(function(error) {
  45. console.log(error);
  46. });
  47. },
  48. remove: function() {
  49. axios.delete("http://localhost:8080/mvc08/emps/2")
  50. .then(r=>vm.msg=r.data.data)
  51. .catch(e=>console.log(e));
  52. }
  53. }
  54. });
  55. </script>
  56. </body>
  57.  
  58. </html>

结果:

1.3、帮助说明(API)

可以通过将相关配置传递给 axios 来进行请求。

1.3.1、axios(config)

  1. //发送一个 POST 请求
  2. axios({
  3. method: 'post',
  4. url: '/user/12345',
  5. data: {
  6. firstName: 'Fred',
  7. lastName: 'Flintstone'
  8. }
  9. });

1.3.2、axios(url[, config])

  1. // 发送一个 GET 请求 (GET请求是默认请求模式)
  2. axios('/user/12345');

1.3.3、请求方法别名

为了方便起见,已经为所有支持的请求方法提供了别名。

  1. axios.requestconfig
  2. axios.geturl [,config])
  3. axios.deleteurl [,config])
  4. axios.headurl [,config])
  5. axios.posturl [,data [,config]])
  6. axios.puturl [,data [,config]])
  7. axios.patchurl [,data [,config]])

注意当使用别名方法时,不需要在config中指定url,method和data属性。

1.3.4、并发

帮助函数处理并发请求。

  1. axios.alliterable
  2. axios.spreadcallback

1.3.5、创建实例

您可以使用自定义配置创建axios的新实例。

axios.create([config])

  1. var instance = axios.create({
  2.   baseURL: 'https://some-domain.com/api/',
  3.   timeout: 1000,
  4.   headers: {'X-Custom-Header': 'foobar'}
  5. });

示例(自定义实例$$,替代axios,统一url):

  1. <!DOCTYPE html>
  2. <html>
  3.  
  4. <head>
  5. <meta charset="UTF-8">
  6. <title>axios</title>
  7. </head>
  8.  
  9. <body>
  10. <div id="vm">
  11. <button type="button" @click="all">all请求(并发请求)</button>
  12. <button type="button" @click="remove">delete请求(删除数据)</button>
  13. <h3>{{msg}}</h3>
  14. </div>
  15. <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
  16. <script src="../js/axios/axios.min.js" type="text/javascript" charset="utf-8"></script>
  17. <script type="text/javascript">
  18.  
  19. //创建自定义的axios实例
  20. var $$=axios.create({
  21. baseURL:"http://localhost:8080/mvc08/emps/"
  22. });
  23.  
  24. console.log($$);
  25.  
  26. var vm = new Vue({
  27. el: "#vm",
  28. data: {
  29. msg: ""
  30. },
  31. methods: {
  32. all: function() {
  33. //获得用户对象1
  34. var getUser1 = function() {
  35. return $$({
  36. url:"1",
  37. method:"get"
  38. });
  39. };
  40. //获得用户对象2
  41. var getUser2 = function() {
  42. return $$.get("24");
  43. };
  44. //并发请求处理结果
  45. axios.all([getUser1(), getUser2()])
  46. .then(axios.spread(function(response1, response2) {
  47. var result = "";
  48. result += JSON.stringify(response1.data.data);
  49. result += JSON.stringify(response2.data.data);
  50. vm.msg = result;
  51. }))
  52. .catch(function(error) {
  53. console.log(error);
  54. });
  55. },
  56. remove: function() {
  57. $$.delete("2")
  58. .then(r=>vm.msg=r.data.data)
  59. .catch(e=>console.log(e));
  60. }
  61. }
  62. });
  63. </script>
  64. </body>
  65.  
  66. </html>

结果:

1.3.6、实例方法

可用的实例方法如下所示。 指定的配置将与实例配置合并。

  1. axiosrequestconfig
  2. axiosgeturl [,config])
  3. axiosdeleteurl [,config])
  4. axiosheadurl [,config])
  5. axiosposturl [,data [,config]])
  6. axiosputurl [,data [,config]])
  7. axiospatchurl [,data [,config]])

1.3.7、请求配置

这些是用于发出请求的可用配置选项。 只有url是必需的。 如果未指定方法,请求将默认为GET。

  1. {
  2. // `url`是将用于请求的服务器URL
  3. url: '/user',
  4.  
  5. // `method`是发出请求时使用的请求方法
  6. method: 'get', // 默认
  7.  
  8. // `baseURL`将被添加到`url`前面,除非`url`是绝对的。
  9. // 可以方便地为 axios 的实例设置`baseURL`,以便将相对 URL 传递给该实例的方法。
  10. baseURL: 'https://some-domain.com/api/',
  11.  
  12. // `transformRequest`允许在请求数据发送到服务器之前对其进行更改
  13. // 这只适用于请求方法'PUT','POST'和'PATCH'
  14. // 数组中的最后一个函数必须返回一个字符串,一个 ArrayBuffer或一个 Stream
  15.  
  16. transformRequest: [function (data) {
  17. // 做任何你想要的数据转换
  18.  
  19. return data;
  20. }],
  21.  
  22. // `transformResponse`允许在 then / catch之前对响应数据进行更改
  23. transformResponse: [function (data) {
  24. // Do whatever you want to transform the data
  25.  
  26. return data;
  27. }],
  28.  
  29. // `headers`是要发送的自定义 headers
  30. headers: {'X-Requested-With': 'XMLHttpRequest'},
  31.  
  32. // `params`是要与请求一起发送的URL参数
  33. // 必须是纯对象或URLSearchParams对象
  34. params: {
  35. ID: 12345
  36. },
  37.  
  38. // `paramsSerializer`是一个可选的函数,负责序列化`params`
  39. // (e.g. https://www.npmjs.com/package/qs, http://api.jquery.com/jquery.param/)
  40. paramsSerializer: function(params) {
  41. return Qs.stringify(params, {arrayFormat: 'brackets'})
  42. },
  43.  
  44. // `data`是要作为请求主体发送的数据
  45. // 仅适用于请求方法“PUT”,“POST”和“PATCH”
  46. // 当没有设置`transformRequest`时,必须是以下类型之一:
  47. // - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
  48. // - Browser only: FormData, File, Blob
  49. // - Node only: Stream
  50. data: {
  51. firstName: 'Fred'
  52. },
  53.  
  54. // `timeout`指定请求超时之前的毫秒数。
  55. // 如果请求的时间超过'timeout',请求将被中止。
  56. timeout: 1000,
  57.  
  58. // `withCredentials`指示是否跨站点访问控制请求
  59. // should be made using credentials
  60. withCredentials: false, // default
  61.  
  62. // `adapter'允许自定义处理请求,这使得测试更容易。
  63. // 返回一个promise并提供一个有效的响应(参见[response docs](#response-api))
  64. adapter: function (config) {
  65. /* ... */
  66. },
  67.  
  68. // `auth'表示应该使用 HTTP 基本认证,并提供凭据。
  69. // 这将设置一个`Authorization'头,覆盖任何现有的`Authorization'自定义头,使用`headers`设置。
  70. auth: {
  71. username: 'janedoe',
  72. password: 's00pers3cret'
  73. },
  74.  
  75. // “responseType”表示服务器将响应的数据类型
  76. // 包括 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'
  77. responseType: 'json', // default
  78.  
  79. //`xsrfCookieName`是要用作 xsrf 令牌的值的cookie的名称
  80. xsrfCookieName: 'XSRF-TOKEN', // default
  81.  
  82. // `xsrfHeaderName`是携带xsrf令牌值的http头的名称
  83. xsrfHeaderName: 'X-XSRF-TOKEN', // default
  84.  
  85. // `onUploadProgress`允许处理上传的进度事件
  86. onUploadProgress: function (progressEvent) {
  87. // 使用本地 progress 事件做任何你想要做的
  88. },
  89.  
  90. // `onDownloadProgress`允许处理下载的进度事件
  91. onDownloadProgress: function (progressEvent) {
  92. // Do whatever you want with the native progress event
  93. },
  94.  
  95. // `maxContentLength`定义允许的http响应内容的最大大小
  96. maxContentLength: 2000,
  97.  
  98. // `validateStatus`定义是否解析或拒绝给定的promise
  99. // HTTP响应状态码。如果`validateStatus`返回`true`(或被设置为`null` promise将被解析;否则,promise将被
  100. // 拒绝。
  101. validateStatus: function (status) {
  102. return status >= 200 && status < 300; // default
  103. },
  104.  
  105. // `maxRedirects`定义在node.js中要遵循的重定向的最大数量。
  106. // 如果设置为0,则不会遵循重定向。
  107. maxRedirects: 5, // 默认
  108.  
  109. // `httpAgent`和`httpsAgent`用于定义在node.js中分别执行http和https请求时使用的自定义代理。
  110. // 允许配置类似`keepAlive`的选项,
  111. // 默认情况下不启用。
  112. httpAgent: new http.Agent({ keepAlive: true }),
  113. httpsAgent: new https.Agent({ keepAlive: true }),
  114.  
  115. // 'proxy'定义代理服务器的主机名和端口
  116. // `auth`表示HTTP Basic auth应该用于连接到代理,并提供credentials。
  117. // 这将设置一个`Proxy-Authorization` header,覆盖任何使用`headers`设置的现有的`Proxy-Authorization` 自定义 headers。
  118. proxy: {
  119. host: '127.0.0.1',
  120. port: 9000,
  121. auth: : {
  122. username: 'mikeymike',
  123. password: 'rapunz3l'
  124. }
  125. },
  126.  
  127. // “cancelToken”指定可用于取消请求的取消令牌
  128. // (see Cancellation section below for details)
  129. cancelToken: new CancelToken(function (cancel) {
  130. })
  131. }

使用 then 时,您将收到如下响应:

  1. axios.get('/user/12345')
  2. .then(function(response) {
  3.   console.log(response.data);
  4.   console.log(response.status);
  5.   console.log(response.statusText);
  6.   console.log(response.headers);
  7.   console.log(response.config);
  8. });

1.4、配置默认值

您可以指定将应用于每个请求的配置默认值。

1.4.1、全局axios默认值

  1. axios.defaults.baseURL = 'https://api.example.com';
  2. axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
  3. axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

1.4.2、自定义实例默认值

  1. //在创建实例时设置配置默认值
  2. var instance = axios.create({
  3.   baseURL'https://api.example.com'
  4. });
  5.  
  6. //在实例创建后改变默认值
  7. instance.defaults.headers.common ['Authorization'] = AUTH_TOKEN;

1.4.3、配置优先级顺序

配置将与优先顺序合并。 顺序是lib / defaults.js中的库默认值,然后是实例的defaults属性,最后是请求的config参数。 后者将优先于前者。 这里有一个例子。

  1. //使用库提供的配置默认值创建实例
  2. //此时,超时配置值为`0`,这是库的默认值
  3. var instance = axios.create();
  4.  
  5. //覆盖库的超时默认值
  6. //现在所有请求将在超时前等待2.5秒
  7. instance.defaults.timeout = 2500;
  8.  
  9. //覆盖此请求的超时,因为它知道需要很长时间
  10. instance.get'/ longRequest',{
  11. timeout5000
  12. });

1.5、拦截器

你可以截取请求或响应在被 then 或者 catch 处理之前

  1. //添加请求拦截器
  2. axios.interceptors.request.usefunctionconfig){
  3. //在发送请求之前做某事
  4. return config;
  5. },functionerror){
  6. //请求错误时做些事
  7. return Promise.rejecterror);
  8. });
  9.  
  10. //添加响应拦截器
  11. axios.interceptors.response.usefunctionresponse){
  12. //对响应数据做些事
  13. return response;
  14. },functionerror){
  15. //请求错误时做些事
  16. return Promise.rejecterror);
  17. });

如果你以后可能需要删除拦截器。

  1. var myInterceptor = axios.interceptors.request.use(function () {/*...*/});
  2. axios.interceptors.request.eject(myInterceptor);

你可以将拦截器添加到axios的自定义实例。

  1. var instance = axios.create();
  2. instance.interceptors.request.use(function () {/*...*/});

1.6、处理错误

  1. axios.get'/ user / 12345'
  2. .catchfunctionerror){
  3. iferror.response){
  4. //请求已发出,但服务器使用状态代码进行响应
  5. //落在2xx的范围之外
  6. console.logerror.response.data);
  7. console.logerror.response.status);
  8. console.logerror.response.headers);
  9. } else {
  10. //在设置触发错误的请求时发生了错误
  11. console.log'Error'error.message);
  12. }}
  13. console.logerror.config);
  14. });

您可以使用validateStatus配置选项定义自定义HTTP状态码错误范围。

  1. axios.get'/ user / 12345',{
  2.   validateStatusfunctionstatus){
  3.   return status < 500; //仅当状态代码大于或等于500时拒绝
  4.   }}
  5. })

1.7、取消令牌(Cancellation)

您可以使用取消令牌取消请求。

axios cancel token API基于可取消的promise提议,目前处于阶段1。
您可以使用CancelToken.source工厂创建一个取消令牌,如下所示:

  1. var CancelToken = axios.CancelToken;
  2. var source = CancelToken.source();
  3.  
  4. axios.get('/user/12345', {
  5. cancelToken: source.token
  6. }).catch(function(thrown) {
  7. if (axios.isCancel(thrown)) {
  8. console.log('Request canceled', thrown.message);
  9. } else {
  10. // 处理错误
  11. }
  12. });
  13.  
  14. //取消请求(消息参数是可选的)
  15. source.cancel'操作被用户取消。');

您还可以通过将执行器函数传递给CancelToken构造函数来创建取消令牌:

  1. var CancelToken = axios.CancelToken;
  2. var cancel;
  3.  
  4. axios.get'/ user / 12345',{
  5. cancelTokennew CancelTokenfunction executorc){
  6.     //一个执行器函数接收一个取消函数作为参数
  7.     cancel = c;
  8.   })
  9. });
  10.  
  11. // 取消请求
  12. clear();

注意:您可以使用相同的取消令牌取消几个请求。

1.8、使用application / x-www-form-urlencoded格式

默认情况下,axios将JavaScript对象序列化为JSON。 要以应用程序/ x-www-form-urlencoded格式发送数据,您可以使用以下选项之一。

  1. axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

1.8.1、浏览器中

在浏览器中,您可以使用URLSearchParams API,如下所示:

  1. var params = new URLSearchParams();
  2. params.append('param1', 'value1');
  3. params.append('param2', 'value2');
  4. axios.post('/foo', params);

请注意,所有浏览器都不支持URLSearchParams,但是有一个polyfill可用(确保polyfill全局环境)。
或者,您可以使用qs库对数据进行编码:

  1. var qs = require('qs');
  2. axios.post('/foo', qs.stringify({ 'bar': 123 });

1.8.2、Node.js中

在node.js中,可以使用querystring模块,如下所示:

  1. var querystring = require('querystring');
  2. axios.post('http://something.com/', querystring.stringify({ foo: 'bar' });

你也可以使用qs库。

2.9、Promise

axios 依赖本机要支持ES6 Promise实现。 如果您的环境不支持ES6 Promises,您可以使用polyfill。

1.10、TypeScript

axios包括TypeScript定义。

  1. import axios from 'axios';
  2. axios.get('/user?ID=12345');

axios在很大程度上受到Angular提供的$http服务的启发。 最终,axios努力提供一个在Angular外使用的独立的$http-like服务。

二、Lodash

Lodash是一个具有一致接口、模块化、高性能等特性的 JavaScript 工具库。它内部封装了诸多对字符串、数组、对象等常见数据类型的处理函数,其中部分是目前 ECMAScript 尚未制定的规范,但同时被业界所认可的辅助函数。目前每天使用 npm 安装 Lodash 的数量在百万级以上,这在一定程度上证明了其代码的健壮性,值得我们在项目中一试。

官网:https://lodash.com/

中文文档:http://www.css88.com/doc/lodash/

英文帮助:https://lodash.com/docs/

GitHub:https://github.com/lodash/

2.1、下载

CDN引用地址:https://cdn.jsdelivr.net/npm/lodash@4.17.4/lodash.min.js

2.2、安装

浏览器:

  1. <script src="lodash.js"></script>
  2. //或CDN
  3. <script scr="https://cdn.jsdelivr.net/npm/lodash@4.17.4/lodash.min.js"></script>

用npm:

  1. $ npm i -g npm
  2. $ npm i --save lodash

Nodejs:

  1. // Load the full build.
  2. var _ = require('lodash');
  3. // Load the core build.
  4. var _ = require('lodash/core');
  5. // Load the FP build for immutable auto-curried iteratee-first data-last methods.
  6. var fp = require('lodash/fp');
  7.  
  8. // Load method categories.
  9. var array = require('lodash/array');
  10. var object = require('lodash/fp/object');
  11.  
  12. // Cherry-pick methods for smaller browserify/rollup/webpack bundles.
  13. var at = require('lodash/at');
  14. var curryN = require('lodash/fp/curryN');

2.3、模块组成

Lodash 提供的辅助函数主要分为以下几类,函数列表和用法实例请查看 Lodash 的官方文档:

Array,适用于数组类型,比如填充数据、查找元素、数组分片等操作

Collection,适用于数组和对象类型,部分适用于字符串,比如分组、查找、过滤等操作

Function,适用于函数类型,比如节流、延迟、缓存、设置钩子等操作

Lang,普遍适用于各种类型,常用于执行类型判断和类型转换

Math,适用于数值类型,常用于执行数学运算

Number,适用于生成随机数,比较数值与数值区间的关系

Object,适用于对象类型,常用于对象的创建、扩展、类型转换、检索、集合等操作

Seq,常用于创建链式调用,提高执行性能(惰性计算)

String,适用于字符串类型

lodash/fp 模块提供了更接近函数式编程的开发方式,其内部的函数经过包装,具有immutable、auto-curried、iteratee-first、data-last(官方介绍)等特点

2.4、Lodash快速入门实例

2.4.1. N 次循环

  1. // 1. Basic for loop.
  2. for(var i = 0; i < 5; i++) {
  3. // ...
  4. }
  5.  
  6. // 2. Using Array's join and split methods
  7. Array.apply(null, Array(5)).forEach(function(){
  8. // ...
  9. });
  10.  
  11. // Lodash
  12. _.times(5, function(){
  13. // ...
  14. });

for 语句是执行循环的不二选择,Array.apply 也可以模拟循环,但在上面代码的使用场景下,_.times() 的解决方式更加简洁和易于理解。

示例:

  1. <!DOCTYPE html>
  2. <html>
  3.  
  4. <head>
  5. <meta charset="UTF-8">
  6. <title>Lodash</title>
  7. </head>
  8.  
  9. <body>
  10. <div id="vm">
  11.  
  12. </div>
  13. <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
  14. <script src="../js/lodash/lodash.min.js" type="text/javascript" charset="utf-8"></script>
  15. <script type="text/javascript">
  16. var vm = new Vue({
  17. el: "#vm",
  18. data: {
  19. msg: ""
  20. },
  21. methods: {
  22.  
  23. }
  24. });
  25.  
  26. var log = function(str) {
  27. console.log(str);
  28. }
  29.  
  30. log(_.times(5));
  31. log(_.times(5, String));
  32. log(_.times(5, _.constant(0)));
  33. log(_.times(5, _.constant(true)));
  34. var a5=_.times(5, function(v) {
  35. return v+10;
  36. })
  37. log(a5);
  38. </script>
  39. </body>
  40.  
  41. </html>

结果:

2.4.2. 深层查找属性值

  1. // Fetch the name of the first pet from each owner
  2. var ownerArr = [{
  3. "owner": "Colin",
  4. "pets": [{"name":"dog1"}, {"name": "dog2"}]
  5. }, {
  6. "owner": "John",
  7. "pets": [{"name":"dog3"}, {"name": "dog4"}]
  8. }];
  9.  
  10. // Array's map method.
  11. ownerArr.map(function(owner){
  12.   return owner.pets[0].name;
  13. });
  14.  
  15. // Lodash
  16. _.map(ownerArr, 'pets[0].name');

_.map 方法是对原生 map 方法的改进,其中使用 pets[0].name 字符串对嵌套数据取值的方式简化了很多冗余的代码,非常类似使用 jQuery 选择 DOM 节点 ul > li > a,对于前端开发者来说有种久违的亲切感。

示例:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Lodash</title>
  6. </head>
  7. <body>
  8. <script src="../js/lodash/lodash.min.js" type="text/javascript" charset="utf-8"></script>
  9. <script type="text/javascript">
  10. var log = function(str) {
  11. if(typeof str == "object")
  12. {
  13. console.log(JSON.stringify(str));
  14. }
  15. console.log(str);
  16. }
  17.  
  18. var arr = [{
  19. "owner": "Colin",
  20. "pets": [{
  21. "name": "dog1"
  22. }, {
  23. "name": "dog2"
  24. }]
  25. }, {
  26. "owner": "John",
  27. "pets": [{
  28. "name": "dog3"
  29. }, {
  30. "name": "dog4"
  31. }]
  32. }];
  33.  
  34. log(_.map(arr,"pets"));
  35. log(_.map(arr,"owner"));
  36. log(_.map(arr,"pets[1].name"));
  37. log(_.map(arr,o=>o.pets[1].name+":)"));
  38. </script>
  39. </body>
  40.  
  41. </html>

结果:

2.4.3. 个性化数组

  1. // Array's map method.
  2. Array.apply(null, Array(6)).map(function(item, index){
  3. return "ball_" + index;
  4. });
  5.  
  6. // Lodash
  7. _.times(6, _.uniqueId.bind(null, 'ball_'));
  8.  
  9. // Lodash
  10. _.times(6, _.partial(_.uniqueId, 'ball_'));
  11. // eg. [ball_0, ball_1, ball_2, ball_3, ball_4, ball_5]

在上面的代码中,我们要创建一个初始值不同、长度为 6 的数组,其中 _.uniqueId 方法用于生成独一无二的标识符(递增的数字,在程序运行期间保持独一无二),_partial 方法是对 bind 的封装。

示例:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Lodash</title>
  6. </head>
  7. <body>
  8. <script src="../js/lodash/lodash.min.js" type="text/javascript" charset="utf-8"></script>
  9. <script type="text/javascript">
  10. var log = function(str) {
  11. if(typeof str == "object")
  12. {
  13. console.log(JSON.stringify(str));
  14. }
  15. console.log(str);
  16. }
  17. //产生唯一编号
  18. log(_.uniqueId());
  19. log(_.uniqueId("gdnf_"));
  20.  
  21. //封装函数
  22. function greet(greeting,name){
  23. return greeting +" " +name;
  24. }
  25. log(greet("hello","tom"));
  26.  
  27. var sayhello=_.partial(greet,'hello');
  28. var sayhi=_.partial(greet,'hi');
  29.  
  30. log(sayhello('mark'));
  31. log(sayhi('rose'));
  32.  
  33. //综合
  34. var array=_.times(5,_.partial(_.uniqueId,'ball_'));
  35. log(array);
  36. </script>
  37. </body>
  38.  
  39. </html>

结果:

2.4.4. 深拷贝

  1. var objA = {
  2. "name": "colin"
  3. }
  4.  
  5. // Normal method? Too long. See Stackoverflow for solution:
  6. // http://stackoverflow.com/questions/4459928/how-to-deep-clone-in-javascript
  7.  
  8. // Lodash
  9. var objB = _.cloneDeep(objA);
  10. objB === objA // false

JavaScript 没有直接提供深拷贝的函数,但我们可以用其他函数来模拟,比如 JSON.parse(JSON.stringify(objectToClone)),但这种方法要求对象中的属性值不能是函数。Lodash 中的 _.cloneDeep 函数封装了深拷贝的逻辑,用起来更加简洁。

示例:

  1. <!DOCTYPE html>
  2. <html>
  3.  
  4. <head>
  5. <meta charset="UTF-8">
  6. <title>Lodash</title>
  7. </head>
  8.  
  9. <body>
  10. <script src="../js/lodash/lodash.min.js" type="text/javascript" charset="utf-8"></script>
  11. <script type="text/javascript">
  12. var log = function(str) {
  13. if(typeof str == "object") {
  14. console.log(JSON.stringify(str));
  15. }
  16. console.log(str);
  17. }
  18. var obj0={address:"中国珠海"};
  19. var obj1 = {
  20. id: 1,
  21. name: "rose",
  22. position:obj0
  23. };
  24. log("引用");
  25. //引用
  26. var obj2=obj1;
  27. log(obj2==obj1);
  28. log("浅拷贝");
  29. //浅拷贝
  30. var obj3=_.clone(obj1);
  31. log(obj3==obj1);
  32. log(obj3===obj1);
  33. log(obj3.position===obj1.position);
  34. log("深拷贝");
  35. //深拷贝
  36. var obj4=_.cloneDeep(obj1);
  37. log(obj4==obj1);
  38. log(obj4===obj1);
  39. log(obj4.position===obj1.position);
  40. </script>
  41. </body>
  42.  
  43. </html>

结果:

2.4.5. 随机数

  1. // Naive utility method
  2. function getRandomNumber(min, max){
  3. return Math.floor(Math.random() * (max - min + 1)) + min;
  4. }
  5.  
  6. getRandomNumber(15, 20);
  7.  
  8. // Lodash
  9. _.random(15, 20);

Lodash 的随机数生成函数更贴近实际开发,ECMAScript 的随机数生成函数是底层必备的接口,两者都不可或缺。此外,使用 _.random(15, 20, true) 还可以在 15 到 20 之间生成随机的浮点数。

示例:

  1. <!DOCTYPE html>
  2. <html>
  3.  
  4. <head>
  5. <meta charset="UTF-8">
  6. <title>Lodash</title>
  7. </head>
  8.  
  9. <body>
  10. <script src="../js/lodash/lodash.min.js" type="text/javascript" charset="utf-8"></script>
  11. <script type="text/javascript">
  12. var log = function(str) {
  13. if(typeof str == "object") {
  14. console.log(JSON.stringify(str));
  15. }
  16. console.log(str);
  17. }
  18. var obj0={address:"中国珠海"};
  19. var obj1 = {
  20. id: 1,
  21. name: "rose",
  22. position:obj0
  23. };
  24.  
  25. var arr=_.times(10,function(){
  26. return _.random(1,100);
  27. });
  28. log(arr);
  29. </script>
  30. </body>
  31.  
  32. </html>

结果:

2.4.6. 对象扩展

  1. // Adding extend function to Object.prototype
  2. Object.prototype.extend = function(obj) {
  3. for (var i in obj) {
  4. if (obj.hasOwnProperty(i)) {
  5. this[i] = obj[i];
  6. }
  7. }
  8. };
  9.  
  10. var objA = {"name": "colin", "car": "suzuki"};
  11. var objB = {"name": "james", "age": 17};
  12.  
  13. objA.extend(objB);
  14. objA; // {"name": "james", "age": 17, "car": "suzuki"};
  15.  
  16. // Lodash
  17. _.assign(objA, objB);

_.assign 是浅拷贝,和 ES6 新增的 Ojbect.assign 函数功能一致(建议优先使用 Object.assign)。

示例:

  1. <!DOCTYPE html>
  2. <html>
  3.  
  4. <head>
  5. <meta charset="UTF-8">
  6. <title>Lodash</title>
  7. </head>
  8.  
  9. <body>
  10. <script src="../js/lodash/lodash.min.js" type="text/javascript" charset="utf-8"></script>
  11. <script type="text/javascript">
  12. var log = function(str) {
  13. if(typeof str == "object") {
  14. console.log(JSON.stringify(str));
  15. }
  16. console.log(str);
  17. }
  18. var obj0 = {
  19. address: "中国珠海"
  20. };
  21. var obj1 = {
  22. id: 1,
  23. name: "rose",
  24. position: obj0
  25. };
  26.  
  27. var x = {
  28. a: 1,
  29. b: 2,
  30. c: 3
  31. };
  32. var y = {
  33. b: 5,
  34. c: 6,
  35. d: 7
  36. };
  37. //用y扩展x
  38. _.assign(x,y);
  39. log(x); //x被修改了
  40. log(y);
  41. </script>
  42. </body>
  43. </html>

结果:

2.4.7. 筛选属性

  1. // Naive method: Remove an array of keys from object
  2. Object.prototype.remove = function(arr) {
  3. var that = this;
  4. arr.forEach(function(key){
  5. delete(that[key]);
  6. });
  7. };
  8.  
  9. var objA = {"name": "colin", "car": "suzuki", "age": 17};
  10.  
  11. objA.remove(['car', 'age']);
  12. objA; // {"name": "colin"}
  13.  
  14. // Lodash
  15. objA = _.omit(objA, ['car', 'age']);
  16. // => {"name": "colin"}
  17. objA = _.omit(objA, 'car');
  18. // => {"name": "colin", "age": 17};
  19. objA = _.omit(objA, _.isNumber);
  20. // => {"name": "colin"};

大多数情况下,Lodash 所提供的辅助函数都会比原生的函数更贴近开发需求。在上面的代码中,开发者可以使用数组、字符串以及函数的方式筛选对象的属性,并且最终会返回一个新的对象,中间执行筛选时不会对旧对象产生影响。

  1. // Naive method: Returning a new object with selected properties
  2. Object.prototype.pick = function(arr) {
  3. var _this = this;
  4. var obj = {};
  5. arr.forEach(function(key){
  6. obj[key] = _this[key];
  7. });
  8.  
  9. return obj;
  10. };
  11.  
  12. var objA = {"name": "colin", "car": "suzuki", "age": 17};
  13.  
  14. var objB = objA.pick(['car', 'age']);
  15. // {"car": "suzuki", "age": 17}
  16.  
  17. // Lodash
  18. var objB = _.pick(objA, ['car', 'age']);
  19. // {"car": "suzuki", "age": 17}

_.pick 是 _.omit 的相反操作,用于从其他对象中挑选属性生成新的对象。

示例:

  1. <!DOCTYPE html>
  2. <html>
  3.  
  4. <head>
  5. <meta charset="UTF-8">
  6. <title>Lodash</title>
  7. </head>
  8.  
  9. <body>
  10. <script src="../js/lodash/lodash.min.js" type="text/javascript" charset="utf-8"></script>
  11. <script type="text/javascript">
  12. var log = function(str) {
  13. if(typeof str == "object") {
  14. console.log(JSON.stringify(str));
  15. }
  16. console.log(str);
  17. }
  18. var obj0 = {
  19. address: "中国珠海"
  20. };
  21. var obj1 = {
  22. id: 1,
  23. name: "rose",
  24. position: obj0
  25. };
  26.  
  27. var student = {
  28. name: "张三",
  29. age: 18,
  30. address: "中国香港"
  31. };
  32.  
  33. //删除属性地址,未修改原数组
  34. var obj1 = _.omit(student, "address");
  35. log(obj1);
  36.  
  37. var obj2 = _.omit(student, ['age','name']);
  38. log(obj2);
  39. </script>
  40. </body>
  41.  
  42. </html>

结果:

2.4.8. 随机元素

  1. var luckyDraw = ["Colin", "John", "James", "Lily", "Mary"];
  2.  
  3. function pickRandomPerson(luckyDraw){
  4. var index = Math.floor(Math.random() * (luckyDraw.length -1));
  5. return luckyDraw[index];
  6. }
  7.  
  8. pickRandomPerson(luckyDraw); // John
  9.  
  10. // Lodash
  11. _.sample(luckyDraw); // Colin
  12.  
  13. // Lodash - Getting 2 random item
  14. _.sample(luckyDraw, 2); // ['John','Lily']

_.sample 支持随机挑选多个元素并返回新的数组。

示例:

  1. <!DOCTYPE html>
  2. <html>
  3.  
  4. <head>
  5. <meta charset="UTF-8">
  6. <title>Lodash</title>
  7. </head>
  8.  
  9. <body>
  10. <script src="../js/lodash/lodash.min.js" type="text/javascript" charset="utf-8"></script>
  11. <script type="text/javascript">
  12. var log = function(str) {
  13. if(typeof str == "object") {
  14. console.log(JSON.stringify(str));
  15. }
  16. console.log(str);
  17. }
  18. var luckyDraw = ["Colin", "John", "James", "Lily", "Mary"];
  19.  
  20. //随机获得一个
  21. log(_.sample(luckyDraw));
  22. //随机获得多个
  23. log(_.sampleSize(luckyDraw,2));
  24. </script>
  25. </body>
  26.  
  27. </html>

结果:

2.4.9. 针对 JSON.parse 的错误处理

  1. // Using try-catch to handle the JSON.parse error
  2. function parse(str){
  3. try {
  4. return JSON.parse(str);
  5. }
  6.  
  7. catch(e) {
  8. return false;
  9. }
  10. }
  11.  
  12. // With Lodash
  13. function parseLodash(str){
  14. return _.attempt(JSON.parse.bind(null, str));
  15. }
  16.  
  17. parse('a');
  18. // => false
  19. parseLodash('a');
  20. // => Return an error object
  21.  
  22. parse('{"name": "colin"}');
  23. // => Return {"name": "colin"}
  24. parseLodash('{"name": "colin"}');
  25. // => Return {"name": "colin"}

如果你在使用 JSON.parse 时没有预置错误处理,那么它很有可能会成为一个定时炸弹,我们不应该默认接收的 JSON 对象都是有效的。try-catch 是最常见的错误处理方式,如果项目中 Lodash,那么可以使用 _.attmpt 替代 try-catch 的方式,当解析 JSON 出错时,该方法会返回一个 Error 对象。

随着 ES6 的普及,Lodash 的功能或多或少会被原生功能所替代,所以使用时还需要进一步甄别,建议优先使用原生函数。

2.5、更多功能

1) _.map(collection, [iteratee=_.identity], [thisArg])

作用:创建一个经过 iteratee 处理的集合中每一个元素的结果数组. iteratee 会传入3个参数:(value, index|key, collection).

别名(Aliases):_.collect

参数1): 需要遍历的集合,可以是数组,对象或者字符串.

参数2): 迭代器,可以是函数,对象或者字符串.

参数3): 迭代器中this所绑定的对象.

返回值(Array): 映射后的新数组.

示例:

  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])

作用:将 array 拆分成多个 size 长度的块,把这些块组成一个新数组。 如果 array 无法被分割成全部等长的块,那么最后剩余的元素将组成一个块.

参数1): 需要被处理的数组.

参数2): 每个块的长度.

返回值(Array): 返回一个包含拆分块数组的新数组(相当于一个二维数组).

示例:

  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)

作用:创建一个新数组并包含原数组中所有的非假值元素。例如 falsenull、 0""undefined 和 NaN 都是“假值”.

参数: 需要被过滤的数组.

返回值(Array): 过滤假值后的数组.

示例:

  1. _.compact([0, 1, false, 2, '', 3]);
  2. // => [1, 2, 3]

4) _.difference(array, [values])

作用:创建一个差异化后的数组,不包括使用 SameValueZero 方法提供的数组.

参数1): 需要处理的数组.

参数2): 数组需要排除掉的值.

返回值(Array): 过滤后的数组.

示例:

  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])

作用:将 array 中的前 n 个元素去掉,然后返回剩余的部分.

参数1): 被操作的数组.

参数2): 去掉的元素个数.

返回值(Array): 数组的剩余部分.

示例:

  1. _.drop([1, 2, 3]);
  2. // => [2, 3] 默认是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])

作用:将 array 尾部的 n 个元素去除,并返回剩余的部分.

参数1): 需要被处理的数组.

参数2): 去掉的元素个数.

返回值(Array): 数组的剩余部分.

示例:

  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])

作用:从尾端查询(右数)数组 array ,第一个不满足predicate 条件的元素开始截取数组.

参数1): 需要查询的数组.

参数2): 迭代器,可以是函数,对象或者字符串.

参数3): 对应 predicate 属性的值.

返回值(Array): 截取元素后的数组.

示例:

  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)

作用:抽取集合中path所指定的路径的属性值.

参数1): 需要抽取的数组.

参数2): 需要抽取的属性所对应的路径.

返回值(Array): 抽取的属性值所组成的数组.

示例:

  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])

作用:使用 value 值来填充(也就是替换) array,从start位置开始, 到end位置结束(但不包含end位置).

参数1): 需要填充的数组.

参数2): 填充 array 元素的值.

参数3): 起始位置(包含).

参数4): 结束位置(不含).

返回值(Array): 填充后的数组.

示例:

  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])

作用:该方法类似 _.find,区别是该方法返回的是符合 predicate条件的第一个元素的索引,而不是返回元素本身.

参数1): 需要搜索的数组.

参数2): 迭代器,可以是函数,对象或者字符串.

参数3): 对应 predicate 属性的值.

返回值(Number): 符合查询条件的元素的索引值, 未找到则返回 -1.

示例:

  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])

作用:遍历集合中的元素,返回最先经 predicate 检查为真值的元素. predicate 会传入3个元素:(value, index|key, collection).

参数1): 要检索的集合,可以是数组,对象或者字符串.

参数2): 迭代器,可以是函数,对象或者字符串.

参数3): 迭代器中this所绑定的对象.

返回值: 匹配元素,否则返回 undefined.

示例:

  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. // 使用了 `_.matches` 的回调结果
  11. _.find(users, { 'age': 1, 'active': true });
  12. // => 'pebbles'
  13.  
  14. // 使用了 `_.matchesProperty` 的回调结果
  15. _.find(users, ['active', false]);
  16. // => 'fred'
  17.  
  18. // 使用了 `_.property` 的回调结果
  19. _.find(users, 'active');
  20. // => 'barney'

12)_.forEach(collection, [iteratee=_.identity], [thisArg])

作用:调用 iteratee 遍历集合中的元素, iteratee 会传入3个参数:(value, index|key, collection)。 如果显式的返回 false ,iteratee 会提前退出.

参数1): 需要遍历的集合,可以是数组,对象或者字符串.

参数2): 迭代器,只能是函数.

参数3): 迭代器中this所绑定的对象.

返回值: 遍历后的集合.

示例:

  1. _([1, 2]).forEach(function(value) {
  2. console.log(value);
  3. });
  4. // => 输出 `1` 和 `2`
  5.  
  6. _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
  7. console.log(key);
  8. });
  9. // => 输出 'a' 和 'b' (不保证遍历的顺序)

13)_.reduce(collection, [iteratee=_.identity], [accumulator], [thisArg])

作用:通过 iteratee 遍历集合中的每个元素. 每次返回的值会作为下一次 iteratee 使用。如果没有提供accumulator,则集合中的第一个元素作为 accumulator. iteratee 会传入4个参数:(accumulator, value, index|key, collection).

参数1): 需要遍历的集合,可以是数组,对象或者字符串.

参数2): 迭代器,只能是函数.

参数3): 累加器的初始化值.

参数4): 迭代器中this所绑定的对象.

返回值: 累加后的值.

示例:

  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])

作用:通过 predicate 检查集合中的元素是否存在任意真值的元素,只要 predicate 返回一次真值,遍历就停止,并返回 true. predicate 会传入3个参数:(value, index|key, collection).

参数1): 需要遍历的集合,可以是数组,对象或者字符串.

参数2): 迭代器,可以是函数,对象或字符串.

参数3): 迭代器中this所绑定的对象.

返回值: 如果任意元素经 predicate 检查都为真值,则返回true,否则返回 false.

示例:

  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)

作用:创建一个包含 value 的 lodash 对象以开启内置的方法链.方法链对返回数组、集合或函数的方法产生作用,并且方法可以被链式调用.

参数: 需要被包裹成lodash对象的值.

返回值: 新的lodash对象的实例.

示例:

  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'

三、作业

3.1、使用axios+vue2实现<<迷你任务管理>>,MicTodo,要求与步骤如下:

  • 定义后台服务,请注意跨域,也可以简化成同域服务(模拟后台数据)
  • 实现对任务的添加,修改,删除,查询功能
  • 任务中只需要要这些属性(编号id,名称name,状态state),当然加上时间更好
  • 使用Lodash完成搜索功能,可以指定要显示的列

3.2、在Loadsh中找到5个关于集合操作的方法,测试通过,不能与上课示例相同

四、示例下载

https://git.coding.net/zhangguo5/vue2.git

五、视频

https://www.bilibili.com/video/av17503637/

前端MVC Vue2学习总结(六)——axios与跨域HTTP请求、Lodash工具库的更多相关文章

  1. 前端MVC Vue2学习总结(一)——MVC与vue2概要、模板、数据绑定与综合示例

    一.前端MVC概要 1.1.库与框架的区别 框架是一个软件的半成品,在全局范围内给了大的约束.库是工具,在单点上给我们提供功能.框架是依赖库的.Vue是框架而jQuery则是库. 1.2.AMD与CM ...

  2. 前端MVC Vue2学习总结(三)——模板语法、过滤器、计算属性、观察者、Class 与 Style 绑定

    Vue.js 使用了基于 HTML 的模版语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据.所有 Vue.js 的模板都是合法的 HTML ,所以能被遵循规范的浏览器和 HTML 解 ...

  3. 前端MVC Vue2学习总结(八)——前端路由

    路由是根据不同的 url 地址展示不同的内容或页面,早期的路由都是后端直接根据 url 来 reload 页面实现的,即后端控制路由. 后来页面越来越复杂,服务器压力越来越大,随着AJAX(异步刷新技 ...

  4. vue.js axios实现跨域http请求接口

    跨域post实例,用到了qs组件来避开ajax信使请求,并兼容Android. import axios from 'axios'; import qs from 'qs'; axios.post(' ...

  5. 前端MVC Vue2学习总结(二)——Vue的实例、生命周期与Vue脚手架(vue-cli)

    一.Vue的实例 1.1.创建一个 Vue 的实例 每个 Vue 应用都是通过 Vue 函数创建一个新的 Vue 实例开始的: var vm = new Vue({ // 选项 }) 虽然没有完全遵循 ...

  6. 前端MVC Vue2学习总结(七)——ES6与Module模块化、Vue-cli脚手架搭建、开发、发布项目与综合示例

    使用vue-cli可以规范项目,提高开发效率,但是使用vue-cli时需要一些ECMAScript6的知识,特别是ES6中的模块管理内容,本章先介绍ES6中的基础与模块化的内容再使用vue-cli开发 ...

  7. 前端MVC Vue2学习总结(四)——条件渲染、列表渲染、事件处理器

    一.条件渲染 1.1.v-if 在字符串模板中,如 Handlebars ,我们得像这样写一个条件块: <!-- Handlebars 模板 --> {{#if ok}} <h1&g ...

  8. 前端MVC Vue2学习总结(五)——表单输入绑定、组件

    一.表单输入绑定 1.1.基础用法 你可以用 v-model 指令在表单控件元素上创建双向数据绑定.它会根据控件类型自动选取正确的方法来更新元素.尽管有些神奇,但 v-model 本质上不过是语法糖, ...

  9. 前端MVC Vue2学习总结(八)——Vue Router路由、Vuex状态管理、Element-UI

    一.Vue Router路由 二.Vuex状态管理 三.Element-UI Element-UI是饿了么前端团队推出的一款基于Vue.js 2.0 的桌面端UI框架,手机端有对应框架是 Mint U ...

随机推荐

  1. python :ascii codec can't decode byte 0xe8 in posit

    python代码: slide.setAttribute("SlideName", module.slide_name)  slide.setAttribute("Sli ...

  2. POI颜色设置

    package com.java.connect.poi; import java.io.FileOutputStream; import java.io.IOException; import or ...

  3. hdu4932 Miaomiao&#39;s Geometry (BestCoder Round #4 枚举)

    题目链接:pid=4932" style="color:rgb(202,0,0); text-decoration:none">http://acm.hdu.edu ...

  4. 项目实战13—企业级虚拟化Virtualization-KVM技术

    项目实战系列,总架构图 http://www.cnblogs.com/along21/p/8000812.html KVM的介绍.准备工作和qemu-kvm 命令详解 1.介绍 (1)介绍 KVM:就 ...

  5. SpringMVC实现JSON与前台交互

    这几天忙着做学校的项目,感觉好久没有更新博客了,来整理一下. 由于要实现的功能是表单联动,只能自己去写ajax来实现提交给后台接口了,好久没有写前端,好多东西都忘记了,只能可怜巴巴的用原生的js去实现 ...

  6. 自学Zabbix3.8.1.2-可视化Visualisation-Graphs自定义图表

    自学Zabbix3.8.1.2-可视化Visualisation-Graphs自定义图表 自定义图表,如名称所示,提供定制功能.虽然简单的图形可以很好地查看单个项目的数据,但是它们不提供配置功能.因此 ...

  7. 大数据学习(5)MapReduce切片(Split)和分区(Partitioner)

    MapReduce中,分片.分区.排序和分组(Group)的关系图: 分片大小 对于HDFS中存储的一个文件,要进行Map处理前,需要将它切分成多个块,才能分配给不同的MapTask去执行. 分片的数 ...

  8. 获取本地ip

    public void GetLocalIP(string username) { List<string> strIPs = new List<string>(); Netw ...

  9. java基础数据类型包装类

    */ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...

  10. springboot(十三):springboot小技巧

    一些springboot小技巧.小知识点 初始化数据 我们在做测试的时候经常需要初始化导入一些数据,如何来处理呢?会有两种选择,一种是使用Jpa,另外一种是Spring JDBC.两种方式各有区别下面 ...