zoukankan      html  css  js  c++  java
  • 前端MVC Vue2学习总结(六)——axios与跨域HTTP请求、Lodash工具库

    一、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、依赖办法

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

     浏览器可以引入js文件

    1.4、快速入门

    1.4.0、服务器端

    控制器:

    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?"获得数据成功!":"获得数据失败!");
        }
    
        @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?"获得数据成功!":"获得数据失败!");
        }
    
        @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?"获得数据成功!":"获得数据失败!");
        }
    
        @RequestMapping(path = "", method = RequestMethod.POST)
        public AjaxState addEmp(@RequestBody User user) {
            boolean result=userService.addUser(user);
            return new AjaxState(result?"success":"error",user,result?"添加成功!":"添加失败");
        }
    
        @RequestMapping(path = "", method = RequestMethod.PUT)
        public AjaxState updateEmp(@RequestBody User user) {
            boolean result=userService.editUser(user);
            return new AjaxState(result?"success":"error",user,result?"修改成功!":"修改失败");
        }
    
        @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?"删除成功!":"删除失败");
        }
    
    }
    
    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(){}
    }

    跨域设置(任选一种):

    方法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>

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

        <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、发送Get请求

    //向具有指定ID的用户发出请求
    axios.get('/user?ID=123')
    .then(function (response) {
    console.log(response);
    })
    .catch(function (error) {
      console.log(error);
    });
     
    //也可以通过 params 对象传递参数
    axios.get('/user', {
    params: {
      ID: 12345
    }
    })
    .then(function (response) {
      console.log(response);
    })
    .catch(function (error) {
      console.log(error);
    });

    示例:

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title>axios</title>
        </head>
        <body>
            <div id="vm">
                <button type="button" @click="get">Get请求</button>
                <button type="button" @click="getParam">Get请求带参数</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);  //错误this指向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>

    结果:

    get请求

    带参数:

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

    1.4.2、发送Post请求

    axios.post('/user', {
        firstName: 'Fred',
        lastName: 'Flintstone'
      })
      .then(function (response) {
        console.log(response);
      })
      .catch(function (error) {
        console.log(error);
      });

    示例(添加一个用户):

    <!DOCTYPE html>
    <html>
    
        <head>
            <meta charset="UTF-8">
            <title>axios</title>
        </head>
    
        <body>
            <div id="vm">
                <button type="button" @click="get">Get请求</button>
                <button type="button" @click="getParam">Get请求带参数</button>
                <button type="button" @click="post">Post请求带参数</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请求
                            var that = this;
                            axios.get("http://localhost:8080/mvc08/emps").then(function(response) {
                                console.log(response);
                                //this.msg=JSON.stringify(response.data);  //错误this指向window
                                vm.msg = JSON.stringify(response.data);
                                that.msg = JSON.stringify(response.data);
                            }).catch(function(error) {
                                console.log(error);
                            })
                        },
                        getParam: function() { //带参数的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": "张一三",
                                "birthday": "1998-09-08",
                                "address": "中国北京",
                                "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>
    View Code

    结果:

    1.4.3、发送多个并发请求

    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) {
    //两个请求现已完成
    }));

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

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title>axios</title>
        </head>
        <body>
            <div id="vm">
                <button type="button" @click="all">all请求(并发请求)</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(){
                            //获得用户对象1
                            var getUser1=function(){
                                return axios.get("http://localhost:8080/mvc08/emps/1");
                            };
                            //获得用户对象2
                            var getUser2=function(){
                                return axios.get("http://localhost:8080/mvc08/emps/2");
                            };
                            //并发请求处理结果
                            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>

    结果:

    1.4.4、发送Put请求

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

    <!DOCTYPE html>
    <html>
    
        <head>
            <meta charset="UTF-8">
            <title>axios</title>
        </head>
    
        <body>
            <div id="vm">
                <button type="button" @click="all">all请求(并发请求)</button>
                <button type="button" @click="put">put请求(修改数据)</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() {
                            //获得用户对象1
                            var getUser1 = function() {
                                return axios({
                                    url:"http://localhost:8080/mvc08/emps/1",
                                    method:"get"
                                });
                            };
                            //获得用户对象2
                            var getUser2 = function() {
                                return axios.get("http://localhost:8080/mvc08/emps/2");
                            };
                            //并发请求处理结果
                            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": "张学霸",
                                "birthday": "1988-09-08",
                                "address": "中国珠海",
                                "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>

    结果:

    1.4.5、发送Delete请求

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

    <!DOCTYPE html>
    <html>
    
        <head>
            <meta charset="UTF-8">
            <title>axios</title>
        </head>
    
        <body>
            <div id="vm">
                <button type="button" @click="all">all请求(并发请求)</button>
                <button type="button" @click="remove">delete请求(删除数据)</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() {
                            //获得用户对象1
                            var getUser1 = function() {
                                return axios({
                                    url:"http://localhost:8080/mvc08/emps/1",
                                    method:"get"
                                });
                            };
                            //获得用户对象2
                            var getUser2 = function() {
                                return axios.get("http://localhost:8080/mvc08/emps/2");
                            };
                            //并发请求处理结果
                            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>

    结果:

    1.3、帮助说明(API)

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

    1.3.1、axios(config)

    //发送一个 POST 请求
    axios({
        method: 'post',
        url: '/user/12345',
        data: {
            firstName: 'Fred',
            lastName: 'Flintstone'
        }
    });

    1.3.2、axios(url[, config])

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

    1.3.3、请求方法别名

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

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

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

    1.3.4、并发

    帮助函数处理并发请求。

    axios.all(iterable)
    axios.spread(callback)

    1.3.5、创建实例

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

    axios.create([config])

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

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

    <!DOCTYPE html>
    <html>
    
        <head>
            <meta charset="UTF-8">
            <title>axios</title>
        </head>
    
        <body>
            <div id="vm">
                <button type="button" @click="all">all请求(并发请求)</button>
                <button type="button" @click="remove">delete请求(删除数据)</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">
                
                //创建自定义的axios实例
                var $$=axios.create({
                    baseURL:"http://localhost:8080/mvc08/emps/"
                });
                
                console.log($$);
                
                var vm = new Vue({
                    el: "#vm",
                    data: {
                        msg: ""
                    },
                    methods: {
                        all: function() {
                            //获得用户对象1
                            var getUser1 = function() {
                                return $$({
                                    url:"1",
                                    method:"get"
                                });
                            };
                            //获得用户对象2
                            var getUser2 = function() {
                                return $$.get("24");
                            };
                            //并发请求处理结果
                            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>

    结果:

    1.3.6、实例方法

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

    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、请求配置

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

    {
    // `url`是将用于请求的服务器URL
    url: '/user',
    
    // `method`是发出请求时使用的请求方法
    method: 'get', // 默认
    
    // `baseURL`将被添加到`url`前面,除非`url`是绝对的。
    // 可以方便地为 axios 的实例设置`baseURL`,以便将相对 URL 传递给该实例的方法。
    baseURL: 'https://some-domain.com/api/',
    
    // `transformRequest`允许在请求数据发送到服务器之前对其进行更改
    // 这只适用于请求方法'PUT','POST'和'PATCH'
    // 数组中的最后一个函数必须返回一个字符串,一个 ArrayBuffer或一个 Stream
    
    transformRequest: [function (data) {
    // 做任何你想要的数据转换
    
    return data;
    }],
    
    // `transformResponse`允许在 then / catch之前对响应数据进行更改
    transformResponse: [function (data) {
    // Do whatever you want to transform the data
    
    return data;
    }],
    
    // `headers`是要发送的自定义 headers
    headers: {'X-Requested-With': 'XMLHttpRequest'},
    
    // `params`是要与请求一起发送的URL参数
    // 必须是纯对象或URLSearchParams对象
    params: {
    ID: 12345
    },
    
    // `paramsSerializer`是一个可选的函数,负责序列化`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`是要作为请求主体发送的数据
    // 仅适用于请求方法“PUT”,“POST”和“PATCH”
    // 当没有设置`transformRequest`时,必须是以下类型之一:
    // - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
    // - Browser only: FormData, File, Blob
    // - Node only: Stream
    data: {
    firstName: 'Fred'
    },
    
    // `timeout`指定请求超时之前的毫秒数。
    // 如果请求的时间超过'timeout',请求将被中止。
    timeout: 1000,
    
    // `withCredentials`指示是否跨站点访问控制请求
    // should be made using credentials
    withCredentials: false, // default
    
    // `adapter'允许自定义处理请求,这使得测试更容易。
    // 返回一个promise并提供一个有效的响应(参见[response docs](#response-api))
    adapter: function (config) {
    /* ... */
    },
    
    // `auth'表示应该使用 HTTP 基本认证,并提供凭据。
    // 这将设置一个`Authorization'头,覆盖任何现有的`Authorization'自定义头,使用`headers`设置。
    auth: {
    username: 'janedoe',
    password: 's00pers3cret'
    },
    
    // “responseType”表示服务器将响应的数据类型
    // 包括 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'
    responseType: 'json', // default
    
    //`xsrfCookieName`是要用作 xsrf 令牌的值的cookie的名称
    xsrfCookieName: 'XSRF-TOKEN', // default
    
    // `xsrfHeaderName`是携带xsrf令牌值的http头的名称
    xsrfHeaderName: 'X-XSRF-TOKEN', // default
    
    // `onUploadProgress`允许处理上传的进度事件
    onUploadProgress: function (progressEvent) {
    // 使用本地 progress 事件做任何你想要做的
    },
    
    // `onDownloadProgress`允许处理下载的进度事件
    onDownloadProgress: function (progressEvent) {
    // Do whatever you want with the native progress event
    },
    
    // `maxContentLength`定义允许的http响应内容的最大大小
    maxContentLength: 2000,
    
    // `validateStatus`定义是否解析或拒绝给定的promise
    // HTTP响应状态码。如果`validateStatus`返回`true`(或被设置为`null` promise将被解析;否则,promise将被
    // 拒绝。
    validateStatus: function (status) {
    return status >= 200 && status < 300; // default
    },
    
    // `maxRedirects`定义在node.js中要遵循的重定向的最大数量。
    // 如果设置为0,则不会遵循重定向。
    maxRedirects: 5, // 默认
    
    // `httpAgent`和`httpsAgent`用于定义在node.js中分别执行http和https请求时使用的自定义代理。
    // 允许配置类似`keepAlive`的选项,
    // 默认情况下不启用。
    httpAgent: new http.Agent({ keepAlive: true }),
    httpsAgent: new https.Agent({ keepAlive: true }),
    
    // 'proxy'定义代理服务器的主机名和端口
    // `auth`表示HTTP Basic auth应该用于连接到代理,并提供credentials。
    // 这将设置一个`Proxy-Authorization` header,覆盖任何使用`headers`设置的现有的`Proxy-Authorization` 自定义 headers。
    proxy: {
    host: '127.0.0.1',
    port: 9000,
    auth: : {
    username: 'mikeymike',
    password: 'rapunz3l'
    }
    },
    
    // “cancelToken”指定可用于取消请求的取消令牌
    // (see Cancellation section below for details)
    cancelToken: new CancelToken(function (cancel) {
    })
    }

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

    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、配置默认值

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

    1.4.1、全局axios默认值

    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、自定义实例默认值

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

    1.4.3、配置优先级顺序

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

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

    1.5、拦截器

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

    //添加请求拦截器
    axios.interceptors.request.use(function(config){
    //在发送请求之前做某事
    return config;
    },function(error){
    //请求错误时做些事
    return Promise.reject(error);
    });
    
    //添加响应拦截器
    axios.interceptors.response.use(function(response){
    //对响应数据做些事
    return response;
    },function(error){
    //请求错误时做些事
    return Promise.reject(error);
    });

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

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

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

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

    1.6、处理错误

    axios.get('/ user / 12345')
    .catchfunction(error){
    if(error.response){
        //请求已发出,但服务器使用状态代码进行响应
        //落在2xx的范围之外
        console.log(error.response.data);
        console.log(error.response.status);
        console.log(error.response.headers);
    } else {
        //在设置触发错误的请求时发生了错误
        console.log('Error',error.message);
    }}
        console.log(error.config);
    });

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

    axios.get('/ user / 12345',{
      validateStatus:function(status){
      return status < 500; //仅当状态代码大于或等于500时拒绝
      }}
    })

    1.7、取消令牌(Cancellation)

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

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

    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 {
    // 处理错误
    }
    });
    
    //取消请求(消息参数是可选的)
    source.cancel('操作被用户取消。');

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

    var CancelToken = axios.CancelToken;
    var cancel;
    
    axios.get('/ user / 12345',{
    cancelToken:new CancelToken(function executor(c){
        //一个执行器函数接收一个取消函数作为参数
        cancel = c;
      })
    });
    
    // 取消请求
    clear();

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

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

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

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

    1.8.1、浏览器中

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

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

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

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

    1.8.2、Node.js中

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

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

    你也可以使用qs库。

    2.9、Promise

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

    1.10、TypeScript

    axios包括TypeScript定义。

    import axios from 'axios';
    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、安装

    浏览器:

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

    用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、模块组成

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

    示例:

    <!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>

    结果:

    2.4.2. 深层查找属性值

    // 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');

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

    示例:

    <!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>

    结果:

    2.4.3. 个性化数组

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

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

    示例:

    <!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);
                }
                //产生唯一编号
                log(_.uniqueId());
                log(_.uniqueId("gdnf_"));
                
                //封装函数
                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'));
                
                //综合
                var array=_.times(5,_.partial(_.uniqueId,'ball_'));
                log(array);
            </script>
        </body>
    
    </html>

    结果:

    2.4.4. 深拷贝

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

    示例:

    <!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:"中国珠海"};
                var obj1 = {
                    id: 1,
                    name: "rose",
                    position:obj0
                };
                log("引用");
                //引用
                var obj2=obj1;
                log(obj2==obj1);
                log("浅拷贝");
                //浅拷贝
                var obj3=_.clone(obj1);
                log(obj3==obj1);
                log(obj3===obj1);
                log(obj3.position===obj1.position);
                log("深拷贝");
                //深拷贝
                var obj4=_.cloneDeep(obj1);
                log(obj4==obj1);
                log(obj4===obj1);
                log(obj4.position===obj1.position);
            </script>
        </body>
    
    </html>

    结果:

    2.4.5. 随机数

    // Naive utility method
    function getRandomNumber(min, max){
    return Math.floor(Math.random() * (max - min + 1)) + min;
    }
    
    getRandomNumber(15, 20);
    
    // Lodash
    _.random(15, 20);

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

    示例:

    <!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:"中国珠海"};
                var obj1 = {
                    id: 1,
                    name: "rose",
                    position:obj0
                };
                
                var arr=_.times(10,function(){
                    return _.random(1,100);
                });
                log(arr);
            </script>
        </body>
    
    </html>

    结果:

    2.4.6. 对象扩展

    // 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 是浅拷贝,和 ES6 新增的 Ojbect.assign 函数功能一致(建议优先使用 Object.assign)。

    示例:

    <!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: "中国珠海"
                };
                var obj1 = {
                    id: 1,
                    name: "rose",
                    position: obj0
                };
    
                var x = {
                    a: 1,
                    b: 2,
                    c: 3
                };
                var y = {
                    b: 5,
                    c: 6,
                    d: 7
                };
                //用y扩展x
                _.assign(x,y);
                log(x);  //x被修改了
                log(y);
            </script>
        </body>
    </html>

    结果:

    2.4.7. 筛选属性

    // 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"};

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

    // 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}

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

    示例:

    <!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: "中国珠海"
                };
                var obj1 = {
                    id: 1,
                    name: "rose",
                    position: obj0
                };
    
                var student = {
                    name: "张三",
                    age: 18,
                    address: "中国香港"
                };
    
                //删除属性地址,未修改原数组
                var obj1 = _.omit(student, "address");
                log(obj1);
                
                var obj2 = _.omit(student, ['age','name']);
                log(obj2);
            </script>
        </body>
    
    </html>

    结果:

    2.4.8. 随机元素

    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 支持随机挑选多个元素并返回新的数组。

    示例:

    <!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"];
                
                //随机获得一个
                log(_.sample(luckyDraw));
                //随机获得多个
                log(_.sampleSize(luckyDraw,2));
            </script>
        </body>
    
    </html>

    结果:

    2.4.9. 针对 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"}

    如果你在使用 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/

  • 相关阅读:
    CSS中position小解
    position
    mac默认安装postgresql, 如何让postgresql可以远程访问
    The data directory was initialized by PostgreSQL version 9.6, which is not compatible with this version 10.0.
    active admin gem error
    psql 无法添加超级用户
    ubuntu 15.04 安装Balsamiq Mockups 3
    Rails html 写public里图片的路径
    rails c 历史命令
    undefined local variable or method `per' for []:ActiveRecord::Relation
  • 原文地址:https://www.cnblogs.com/best/p/8202370.html
Copyright © 2011-2022 走看看