Methods commonly used and Loadsh Loadsh in the vue

Methods commonly used and Loadsh Loadsh in the vue

Lodash is a consistent, modular, high-performance JavaScript utility library. Complex arrays, and contrast of the library can be directly used, but also convenient.

Official website

https://www.lodashjs.com/

A. Debounce function and use of a throttle in the throttle Loadsh in vue

.throttle is lodash throttling function, .debounce is lodash the image stabilization function.
You can see the specific role of official documents directly.

In vue specifically how to use

import _ from 'lodash'
export default{
 methods:{
    click:_.throttle(function(){
            console.log('test')
            console.log(this)
    },1000)
 }
}
import _ from 'lodash'
export default{
 methods:{
 onUpdateNote: _.debounce(function() {
      this.updateNote({ noteId: this.curNote.id, title: this.curNote.title, content: this.curNote.content })
        .then(data => {
          this.statusText = '已保存'
        }).catch(data => {
          this.statusText = '保存出错'
        })
    }, 300)
}

In the throttle, debounce lodash method, a function can be used directly, without the need to re-point to this, in the internal function Apply has been done, so the point here is that this vue example, the outside layer of the package has a function of .throttle /.debounce it.

II. Another method uses debounce and the throttle in vue

1, the installation

cnpm i lodash -S

2, a method of using Global

  • Introduced
import _ from 'lodash'
Vue.prototype._ = _
  • use
this._.debounce(this.handleClick,1000,false)

3, two topical method

  • Introduced
let _ = require('lodash')
  • use
_.debounce(this.handleClick,1000,false)

4, vue single file used in the assembly

Inside respectively, I wrote it myself debounce function and lodash the debounce function, the same effect!

<template>
  <div>
    <el-button @click="myDebounce">我的debounce</el-button>
    <el-button @click="_debounce">lodash的debounce</el-button>
  </div>
</template>

<script>
import { debounce } from '@/utils/util'
let _ = require('lodash')
export default {
  methods: {
    handleClick1() {
      console.log(`真正执行的函数,次数比较少:handleClick1.....`)
    },
    handleClick2() {
      console.log(`真正执行的函数,次数比较少:handleClick2.....`)
    },
    myDebounce() {
      console.log(`myDebounce.....`)
      this.DB()
    },
    _debounce() {
      console.log(`_debounce.....`)
       this._DB()
    }
  },
  created() {
    this.DB = debounce(this.handleClick1, 1000, false)
    this._DB = this._.debounce(this.handleClick2,1000,false)
  }
}
</script>

Note: I used to be defined in the data options inside, then methods which initialization function, but need to determine 'if they have not assigned a function, if it is empty Fu', found too much trouble; later defined directly created hook inside, very convenient! Or after mounted.

Three. Loadsh study notes

Has many years of experience in the development of engineers, often will have their own set of tools library called utils, helpers, etc. This library uses the one hand, their accumulation of technology, on the other hand is an extension of a technology, ahead of the technology specification development and implementation.

Lodash a tool magazine is such that inside the package handler of many strings, arrays, and other common data type of the object, wherein the portion is not developed ECMAScript specification, but are recognized by the industry helper functions. Specialties of Local daily number Lodash npm installed in more than one million, demonstrating the robustness of its code to a certain extent, it is worth a try in the project.

Modules

Lodash hear auxiliary function is divided into the following categories, the list of functions and usage, please see the strength Lodash official document:

  • The Array, suitable for array types, such as padding data, find elements, an array slice and other operations
  • Collocation, and arrays applies to the object type, suitable for the string portion, such as a packet, to find, such as filtration
  • Function, applicable to the function type, such as a throttle, delay, cache, set operations such as hooks
  • Lang, generally applicable to all types, the type commonly used in the determination and execution type conversion
  • The Math, using the value type, commonly used in performing mathematical operations
  • Number, adapted to generate a random number, comparing the relationship between the numerical value range
  • Object, applicable to the type of the object, the object used to create, expand, type conversion, retrieval, and other operations set
  • Seq, commonly used in the call to create a chain to improve execution performance (lazy evaluation)
  • String, applies to string types
  • lodash / fp module provides a method to develop closer functional programming, a function of packaged inside, having immutable, auto-curried, iteratee-first, data-last (official description) and so on.
  • Fixed Arity, the number of curing parameters, facilitate currying
  • Rearragned Arguments, readjust the parameters of position, function to facilitate the polymerization between
  • Capped Iteratee Argument, encapsulation parameters Iteratee

In React + Webpack + Babel (ES6) development environment, using Lodash need to install the plug-babel-plugin-lodash Babel and update the configuration file:

npm install --save lodash
npm install --save-dev babel-plugin-lodash

Update Bable profile .babelrc:

Copy the code

{
    "presets":[
        "react",
        "es2015",
        "stage-0"
    ],
    "plugins":[
        "lodash"
    ]
}

Copy the code

Use:

import _ from 'lodash';
import { add } from 'lodash/fp';

const addOne = add(1);
_.map([1, 2, 3], addOne);

performance

In Filip Zawada article "? To Speed Up Lo-Dash × 100 Introducing Lazy Evaluation How" mentioned the idea Lodash increase execution speed, three main points: Lazy Evaluation, Pipelining and Deferred Execution. The following two graphs from Filip's blog:

img

Hypothetical question like shown above: three balls removed from the face value of less than 10 in a number of requirements. The first step is removed from all of the requirements of all denominations of less than 10 balls, three balls of the second part is to go from the result of the previous step.

img

The figure is another solution, if a ball through the first step, then proceed to the second step, and then until the end of the test the next ball. . . When we get to three balls on the break the cycle. Filip said this is Lazy Evaluation Algorithm, personally understand this is not comprehensive, Pipelining his subsequent mentioned (pipeline computing), plus an algorithm execution cycle interrupt should be more in line illustrated here.

In addition, when using Lodash chain calls, only the reality or implicit call .value method of the entire operation will be called value chain, evaluated immediately when this is not a statement, while job hunting manner when in use, Lazy Evaluation is the biggest feature.

Nine examples

Gains in popularity Lodash, and use it to improve the efficiency of development when many people are in the code, reduce misunderstanding (Loss of Consciousness) between each other. In "Lodash: 10 Javascript Utility Functions That You Should Probably Stop Rewriting" the article, the author lists a number of commonly used Lodash functions, the examples demonstrate the skills to use Lodash.

1. N cycles

Copy the code

// 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(){
    //...
});

Copy the code

for the implementation of the statement is the choice unreal, Array.apply cycle can be simulated, but in the usage scenarios above code, _. tiems () solution is more concise and easy to understand.

2. Deep Find property values

Copy the code

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

Copy the code

_.map method is a modification of the original map method, in which pets [0] .name string of data values ​​in a nested manner simplifies many of the redundant code is very similar to the DOM node to select with jQuery ul> li> a for front-end developers returning to a kind of intimacy.

3. Personalized array

Copy the code

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

Copy the code

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

4. 深拷贝

Copy the code

var objA = {
    "name": "colin"
}

// 常用的方法一般会比较长,循环对象等
// http://stackoverflow.com/questions/4459928/how-to-deep-clone-in-javascript

// Lodash
var objB = _.cloneDeep(objA);
objB === objA // false

Copy the code

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

5. 随机数

Copy the code

// Native utility method
function getRandomNumber(min, max){
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

getRandomNumber(15, 20);

// Lodash
_.random(15, 20);

Copy the code

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

6. 对象扩展

Copy the code

// 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, ojbB);

Copy the code

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

7. 筛选属性

Copy the code

// Native method: Remove an array of keys from object
Object.prototype.remove = function(arr) {
    var that = this;
    arr.forEach(function(key){
        delete(this[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", "car": "suzuki"};

Copy the code

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

Copy the code

// Native method: Returning a new object with selected properties
Object.prototype.pick = function(arr) {
    var _this = this;
    var obj = {};
    arr.forEach(function(){
        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}

Copy the code

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

8.随机元素

Copy the code

var luckDraw = ["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']

Copy the code

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

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

Copy the code

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

Copy the code

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

随着ES6的普及,Lodash的功能或多或少会被原生功能所替代,所以使用时还需要进一步甄别,建议优先使用原生函数,有关ES6替代Lodash的部分,请参考文章《10 个可用 ES6 替代的 Lodash 特性》

其中有两处分厂值得一看:

Copy the code

// 使用箭头函数创建可复用的路径
const object = { 'a': [{ 'b': { 'c': 3 } }, 4] };

[
    obj => obj.a[0].b.c,
    obj => ojb.a[1]
].map(path => path(object));

// 使用箭头函数编写链式调用
const pipe = function => data => {
    return functions.reduce(
        (value, func) => func(value),
        data
    );
};

const pipeline = pipe([
    x => x * 2,
    x => x / 3,
    x => x > 5,
    b => !b
]);

pipeline(5);
// true
pipeline(20);
// false

Copy the code

在ES6中,如果一个函数只接收一个形参且函数提示一个 return 语句, 就可以使用箭头函数简化为:

Copy the code

const func = p => v;

// 类似于(不完全相同)
const func = function(p) {
    return v;
}

Copy the code

当有多重嵌套时,可以简化为:

Copy the code

const func = a => b => c => a + b + c;
func(1)(2)(3);
// => 6

// 类似于
const func = function (a) {
    return function (b) {
        return function (c) {
            return a + b + c;
        }
    }
}

Copy the code

四. Loadsh 常用方法总结

日常开发中,通常会对数据,特别是数组和对象进行各种读写等操作:比如去重,拷贝,合并,过滤,求交集,求和等等。根据平时开发中对数据的操作,我对Lodash常见的用法做了以下总结,方便今后的学习和整理。

Array

Create

  • 创建一个数组,元素为0, 1, 2, ... , 23

    _.range([start=0], end, [step=1])

    let arr = _.range(24)
    
    console.log(arr) // [0, 1, 2, 3, ... , 23]
  • 创建一个数组,元素为100, 100, 100, 100, 100

    _.fill(array, value, [start=0], [end=array.length])

    let arr = _.fill(Array(5), 100)
    
    console.log(arr) // [100, 100, 100, 100, 100]

Read

  • 获取数组中最后一个元素

    _.last(array)

    let arr = [1, 2, 3, 4, 5]
    let lastElement = _.last(arr) 
    
    console.log(lastElement) // 5
  • 获取数组中倒数第二个元素

    _.nth(array, [n=0])

    let arr = [1, 2, 3, 4, 5]
    let lastSecondElement = _.nth(-2) 
    
    console.log(lastSecondElement) // 4
  • 获取对象数组中某一同名属性的属性值集合

    *.map(collection, [iteratee=*.identity])

    let users = [{
          id: 12,
          name: 'Adam',
          hobbies: [
            {name: 'running', index: 100},
            {name: 'cycling', index: 95}
          ]
       },{
          id: 14,
          name: 'Bob',
          hobbies: [
            {name: 'movie', index: 98},
            {name: 'music', index: 85}
          ]
       },{
          id: 16,
          name: 'Charlie',
          hobbies: [
           {name: 'travelling', index: 90},
           {name: 'fishing', index: 88}
          ]
       },{
          id: 18,
          name: 'David',
          hobbies: [
           {name: 'walking', index: 99},
           {name: 'football', index: 85}
         ]                
    
    
       }
    ]
    let userIds = _.map(users, 'id')
    let mostFavouriteHobbies = _.map(users, 'hobbies[0].name')
    
    console.log(userIds) // [12, 14, 16, 18]
    console.log(mostFavouriteHobbies) // ["running", "movie", "travelling", "walking"]
  • 获取对象数组中某一属性值最大的对象

    *.maxBy(array, [iteratee=*.identity])

    let arr = [{a:1, b: 2, c: {d:4}}, {a:3, b: 4, c: {d:6}}]
    let maxBObj = _.maxBy(arr, 'b')
    
    console.log(maxBObj) // {a: 3, b: 4, c: {d: 6}}
  • 找出两个数组中元素值相同的元素

    _.intersection([arrays])

    let arr1 = [2, 1, {a: 1, b: 2}]
    let arr2 = [2, 3, {a: 1, b: 2}]
    let intersection = _.intersection(arr1, arr2) 
    
    console.log(intersection) // [2]
  • 求数值数组中元素值的平均数

    _.mean(array)

    let numbers = [1, 2, 3, 4, 5]
    let average = _.mean(numbers)
    
    console.log(average) // 3
  • 求对象数组中某个属性值的平均数

    *.meanBy(array, [iteratee=*.identity])

    let objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }]
    let average = _.meanBy(objects, 'n')
    
    console.log(average) // 5
  • 获取数组中前n个元素,不改变原数组

    _.take(array, [n=1])

    let arr = [1, 2, 3, 4, 5]
    let part1Arr = _.take(arr, 4)
    let part2Arr = _.take(arr, 6)
    let part3Arr = _.take([], 5)
    
    console.log(part1Arr) // [1, 2, 3, 4]
    console.log(part2Arr) // [1, 2, 3, 4, 5]
    console.log(part3Arr) // []

Delete

  • 删除数组中值为falsy的元素

    _.compact(array)

    let arr = [0, 1, false, 2, '', 3, null, undefined, NaN]
    let truthyArr = _.compact(arr) 
    
    console.log(truthyArr) // [1, 2, 3]

Format

  • 去重。

    _.uniq(array)

    let arr = [2, 1, 2, '2', true]
    let uniqArr = _.uniq(arr)
    
    console.log(uniqArr) // [2, 1, '2', true]
  • 排序。对象数组,根据对象中的某个属性的值,升序或降序排序

    *.orderBy(collection, [iteratees=[*.identity]], [orders])

    let users = [
      {user: 'Tom', age: 25},
      {user: 'Amy', age: 23},
      {user: 'Perter', age: 22},
      {user: 'Ben', age: 29}
    ]
    let sortedUsers = _.orderBy(users, 'age', 'desc')
    
    console.log(sortedUsers)
    // [{user: "Ben", age: 29}, {user: "Tom", age: 25}, {user: "Amy", age: 23}, {user: "Perter", age: 22}]
  • 分割数组[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]为 [1, 2, 3, 4, 5] 和 [6, 7, 8, 9, 10]

    _.chunk(array, [size=1])

    let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    let [left, right] = _.chunk(arr, 5)
    
    console.log(left) // [1, 2, 3, 4, 5]
    console.log(right) // [6, 7, 8, 9, 10]
  • 脱掉一层[]

    _.flatten(array)

    let address = {
      '江苏省': ['南京市', '苏州市'],
      '浙江省': ['杭州市', '绍兴市']
    }
    let cities = _.flatten(_.values(address))
    
    console.log(cities) // ["南京市", "苏州市", "杭州市", "绍兴市"]
  • 将多维数组转为一维数组

    _.flattenDeep(array)

    let flattenedArr = _.flattenDeep([1, [2, [3, [4]], 5]]);
    
    console.log(flattenedArr) // [1, 2, 3, 4, 5]

Object

Create

  • 通过数组["x", "y"] 和 数组[10, 10] 创建对象 {x: 10, y: 10}

    _.zipObject([props=[]], [values=[]])

    let keys = ["x", "y"]
    let values = [10, 10]
    let obj = _.zipObject(keys, values) 
    
    console.log(obj) // {x: 10, y: 10}
  • 合并对象

    _.assign(object, [sources])

    let desObj = {name: '', gender: 'male', job: 'developer'}
    let sourceObj = {name: 'Tom', job: ''}
    let mergedObj = _.assign(desObj, sourceObj)
    
    console.log(mergedObj) // {name: "Tom", gender: "male", job: ""}
  • 深拷贝对象

    _.cloneDeep(value)

    let sourceObj = {department_id: 1, permissions: {management: [1, 2, 3, 4], store: [11, 12, 13, 14]}}
    let desObj = _.cloneDeep(sourceObj)
    desObj.permissions.store.push(15, 16)
    
    console.log(desObj)
    // {department_id: 1, permissions: {management: [1, 2, 3, 4], store: [11, 12, 13, 14, 15, 16]}}
    console.log(sourceObj)
    // {department_id: 1, permissions: {management: [1, 2, 3, 4], store: [11, 12, 13, 14]}}
  • 合并多个对象中key值相同的键值对

    _.merge(object, [sources])

    let obj1 = {'9': {name: '乐购超市'}}
    let obj2 = {'9': {storeToken: 'xxx'}}
    let obj3 = {'9': {storePosition: 'Hangzhou'}}
    let mergedObj = _.merge(obj1, obj2, obj3) 
    
    console.log(mergedObj)
    // 9: {name: "乐购超市", storeToken: "xxx", storePosition: "Hangzhou"}

Read

  • 判断对象中是否有某个属性

    _.has(object, path)

    let obj = {a: [{b: {c: 3}}]}
    let hasC = _.has(obj, 'a[0].b.c')
    
    console.log(hasC) // true
  • 获取对象中的某个属性的值

    _.get(object, path, [defaultValue])

    let obj = {a: [{b: {c: 3}}]}
    let c = _.get(obj, 'a[0].b.c')
    
    console.log(c) // 3

Update

  • 设置对象中的某个属性的值

    _.set(object, path, value)

    let obj = {a: [{b: {c: 3}}]}
    let newObj = _.set(obj, 'a[0].b.c', 4);
    
    console.log(obj.a[0].b.c); // 4
  • 对多个对象相同属性的属性值求和。

    let customers = {
      new_customer: {0: 33, 1: 5, ... , 23: 0},
      old_customer: {0: 22, 1: 7, ... , 24: 0}
    }
    let customer = {}
    let keys = _.keys(customers.new_customer)
    let values = _.values(customers)
    _.map(keys, key => {
      customer[key] = _.sumBy(values, key)
    })
    
    customers.customer = customer
    
    console.log(customers)
    // console
    {
      customer: {0: 55, 1: 12, ... , 23: 0}
      new_customer: {0: 33, 1: 5, ... , 23: 0}
      old_customer: {0: 22, 1: 7, ... , 23: 0}
    }

Number

  • 生成一个随机数,范围n~m

    _.random([lower=0], [upper=1], [floating])

    let random1 = _.random(2, 5)
    let random2 = _.random(5)
    
    console.log(random1) // 2, 3, 4, 5
    console.log(random2) // 0, 1, 2, 3, 4, 5

Data Type

  • Analyzing Data Type

    _.isNumber(value)

    _.isInteger(value)

    ...

    _.isPlainObject(value)

    let variable = 'hello';
    // Number
    console.log(_.isNumber(variable));
    // Integer
    console.log(_.isInteger(variable));
    // Boolean
    console.log(_.isBoolean(variable));
    // String
    console.log(_.isString(variable));
    // Null
    console.log(_.isNull(variable));
    // Undefined
    console.log(_.isUndefined(variable));
    // Array
    console.log(_.isArray(variable));
    // Function
    console.log(_.isFunction(variable));
    // Object
    console.log(_.isPlainObject(variable));
    // Date
    console.log(_.isDate(variable));
    
    // DOM element
    console.log(_.isElement(variable));
  • Data type conversion

    • _.toArray

      _.toArray('abc') // ["a", "b", "c"]
    • _.toInteger

      _.toInteger(3.2); // 3
      _.toInteger('3.2'); // 3
    • _.toNumber

      _.toNumber('3.2') // 3.2
    • _.toString

      _.toString(1); // "1"
      _.toString([1, 2, 3]); // "1,2,3"

Useful

  • Repeated many times an element

    *.times(n, [iteratee=*.identity])

    const dateParams = _.times(2, () => '2018-08-27');
    console.log(dateParams) // ["2018-08-27", "2018-08-27"]

Guess you like

Origin www.cnblogs.com/wenqiangit/p/11762459.html