vuex给getter传参的官方例子解读
最近遇到一个需求,需要在使用vuex的getter获取数据的时候传入参数。遇到问题当然首先是查看文档,然鹅,一脸懵逼。当然最后通过我不断的努(bai)力(du) ,终于能够理解那个官方demo了。为了自己以后复习以及服(zhi)务(shi)小(xiang)伙(zhuang)伴(bi),决定把个人理解记录下来,如果各位看官发现有什么问题,请及时和我联系,这样我就知道又有一个 人看了我的文章!!!
官方说明(短小精悍):你也可以通过让 getter
返回一个函数,来实现给 getter
传参。在你对 store
里的数组进行查询时非常有用。
官方demo(一脸懵逼):
getters: {
// ...
getTodoById: (state, getters) => (id) => {
return state.todos.find(todo => todo.id === id)
}
}
store.getters.getTodoById(2) // -> { id: 2, text: '...', done: false }
首先,我遇到的第一个问题就是那个连续不断的箭头函数是什么鬼(不知道箭头函数的麻烦出门自行百度)?当然,这个东西还是比较好办的,箭头函数一大堆看不懂,咱可以 还原成看的懂的啊,说干咱就干。
getTodoById: function(state, getters) {
return function(id) {
return state.todos.find(function(todo) {
return todo.id === id;
})
}
}
store.getters.getTodoById(2) // -> { id: 2, text: '...', done: false }
这里没有涉及到this的引用,就不对this做处理了,效果是一样的。
看到了这里差不多就明白了。
首先:我们使用获得了一个由
store.getters.getTodoById
返回的匿名函数。
然后:我们立刻传入了参数'2
'执行了这个函数。
最后:看起来就像是我们直接传入了参数给store.getters.getTodoById
函数,但是其实getter
是只能接受默认参数的:state
或者一个 可选的其他getter
,并不支持用户随意传入参数。
到这里基本就可以理解上面的官方demo以及正确使用了。
然后,咱们来聊一聊连续箭头函数这个东西。
以下全部转载自:[ES6 高阶箭头函数][1]
先来看下高阶函数定义:
- 接受1个或多个函数作为参数
- 返回函数类型
常规ES6箭头函数用法:(返回值类型)const square = x => x * x;
高阶写法:
const has = p => o => o.hasOwnProperty(p); const sortBy = p => (a, b) => a[p] > b[p];
理解语法
ES5实现高阶函数,也叫柯里化:
function add(x){
return function(y){
return y + x;
};
}
var addTwo = add(2);
addTwo(3); // => 5
add(10)(11); // => 21
add
函数接受x
,返回一个函数接受y
返回y+x
。如何用箭头函数实现同样功能呢?我们知道:
箭头函数体是表达式,并且箭头函数隐式返回表达式,所以为了实现高阶函数,我们可以使箭头函数的函数体为另一个箭头函数:
const add = x => y => y + x;
// outer function: x => [inner function, uses x]
// inner function: y => y + x;
这样我们可以创建一个绑定了x
的内部函数:
const add2 = add(2);// returns [inner function] where x = 2
add2(4); // returns 6: exec inner with y = 4, x = 2
add(8)(7); // 15
这个例子看起来没什么实际作用,但是很好的展示了如何在返回的函数中引用外部参数。
用户排序例子
const has = p => o => o.hasOwnProperty(p);
const sortBy = p => (a, b) => a[p] > b[p];
let result;
let users = [
{ name: 'Qian', age: 27, pets : ['Bao'], title : 'Consultant' },
{ name: 'Zeynep', age: 19, pets : ['Civelek', 'Muazzam'] },
{ name: 'Yael', age: 52, title : 'VP of Engineering'}
];
result = users
.filter(has('pets'))
.sort(sortBy('age'));
上述代码利用了Array
的sort
和 filter
方法,这两个方法都接收一个函数参数,此处我们利用了箭头函数的高阶函数写法返回需要的函数。
对比下直接传入函数的写法:
result = users
.filter(x => x.hasOwnProperty('pets')) //pass Function to filter
.sort((a, b) => a.age > b.age); //pass Function to sort
高阶函数写法:
result = users
.filter(has('pets')) //pass Function to filter
.sort(sortBy('age')); //pass Function to sort
优势在哪?
- 减少代码重复
- 提高代码重用性
- 更容易阅读的代码
假设我们想列出有pets和title的用户,可以采用如下传统写法:result = users .filter(x => x.hasOwnProperty('pets')) .filter(x => x.hasOwnProperty('title'))
采用高阶函数写法:
result = users .filter(has('pets')) .filter(has('title')) ...
可以明显感受到高阶写法更容易写和维护。
更进一步
假设想实现一个过滤器函数完成如下功能:判断一个对象是否包含指定值的key
。之前的has函数用于检查对象key
,我们需要在此基础上加入值的检查:
//[p]roperty, [v]alue, [o]bject:
const is = p => v => o => o.hasOwnProperty(p) && o[p] == v;
// broken down:
// outer: p => [inner1 function, uses p]
// inner1: v => [inner2 function, uses p and v]
// inner2: o => o.hasOwnProperty(p) && o[p] = v;
所以我们的新函数is做了下面三件事:
- 接收属性名返回函数…
- 接收值返回函数…
- 接收对象,并判读该对象是否有指定的属性名和值,并返回
boolean
下面是一个使用is
函数的例子:const titleIs = is('title'); // titleIs == v => o => o.hasOwnProperty('title') && o['title'] == v;
const isContractor = titleIs('Contractor');
// isContractor == o => o.hasOwnProperty('contractor') && o['title'] == 'Contractor';
let contractors = users.filter(isContractor);
let developers = users.filter(titleIs('Developer'));
let user = {name: 'Viola', age: 50, title: 'Actress', pets: ['Zak']};
isEmployed(user); // true
isContractor(user); // false
关于命名习惯
下面的写法需要你花点时间去理解其含义:
const i = x => y => z => h(x)(y) && y[x] == z;
使用一些更明确含义的参数命名:
const is = prop => val => obj => has(prop)(obj) && obj[prop] == val;
###继续
如果我们想进一步提供排序功能,但是仅改为降序排列,或者列出不包含某属性的用户,我们需要重新实现诸如 `sortByDesc` 和 `notHas`这样的新函数吗?答案是不需要,对于最终返回结果是boolean值的高阶函数,我们可以对其进行取反包装,如下:
//take args, pass them thru to function x, invert the result of x
const invert = x => (...args) => !x(...args);
const noPets = invert(hasPets);
let petlessUsersOldestFirst = users
.filter(noPets)
.sort(invert(sortBy('age')));
## 结论
>函数式编程受到越来越多的重视,ES6的箭头函数提供了更简洁方便的JavaScript实现方式,如果你还没有看到这种方法的广泛使用,那么可以预见在未来几个月函数式编程会伴随ES6的普及变得更为流行。即使你不太喜欢这种方式,那么理解高阶函数也是非常有必要的。
原始资料:[Higher order functions in ES6:Easy as a => b => c;][2]
中文摘译版:[ES6 高阶箭头函数][3]
[1]: https://cnodejs.org/topic/56a1d827cd415452622eed07
[2]: https://developer.ibm.com/node/2016/01/11/higher-order-functions-in-es6easy-as-a-b-c/
[3]: https://cnodejs.org/topic/56a1d827cd415452622eed07
共同学习,写下你的评论
评论加载中...
作者其他优质文章