前言
高阶组件在React圈子中是一个很常见的概念,React奉行原则之一就是使用纯函数编程。
但是在Vue圈子大家看起来讨论得比较少,在Vue这边推崇是易用、渐进式开发,所以我们在开发Vue的时候看到的更多的是<template><script><style>
组合,这更加符合以往开发H5的风格。
下面我从基本概念,到实际业务场景,给大家讲讲什么是高阶组件。
一、高阶组件?
高阶组件即高阶函数
,前面我们讲到,React遵循函数式开发,而高阶组件这个概念其实是React社区繁衍出来的概念。
在这里我们要谨记这一句话,组件 = 函数
。
高阶函数,通俗的讲,就是把函数当作参数,传入另外一个函数当中,再返回一个函数。
2.1 高阶函数定义
- 接受1个及1个以上的函数作为参数。
- 高阶函数返回一个函数
2.2 高阶函数例子
了解高阶函数的基本定义,我们就知道其实js中很多高阶函数的运用,举一个常见的求最大值的例子
// 求数组的最大值
const getMaxValue = function(val, fn) {
return fn(val);
};
const Max = function(val) {
return Math.max.apply(null,val)
}
// 在使用的时候
var arr = [1,20,30,4,5]
getMaxValue(arr,Max)
可以看到
Max
函数并作为参数传递给了getMaxValue
函数,并且getMaxValue返回函数。这就是典型的高阶函数
二、实际应用场景
1.1 业务场景
需要你在一个管理后台,将你用的ElementUI的Button的按钮,全部加上防抖功能。
1.2 场景分析
旧代码中有许多按钮,一个一个改不现实,有没有什么办法,给Button包一层,实现自己的逻辑呢?
类似于后端语言常见的,继承
,方法重载
的概念。
我下面用了一个很常见的洋葱模型来解释
1.3 解决方案
上面我们接触到高阶函数的概念,不影响原Button的作用,同时在原Button上的组件做逻辑补充,这不就是高阶组件吗?
在这之前,我们要先介绍一个工具,Vue的render
函数,它长这样子
render: function (createElement) {
return createElement(
...
// 一系列对组件的处理
)
}
这就是标准的高阶函数,传入createElement
函数,同时返回createElement
函数
三、render高阶函数的运用
还是上面的例子,我们来看看render怎样重写elementUi的Button组件
// NewButton.vue
<script>
import { Button } from 'element-ui'
export default {
name: 'Button',
components: { 'el-button': Button },
data() {
return {
timer: null
}
},
methods: {
click() {
// 实现防抖
const that = this
clearTimeout(that.timer)
that.timer = setTimeout(function() {
that.$emit('click')
}, 1000)
;
}
},
render(createElement) {
return createElement(
'el-button',
{
on: { click: this.click }
},
'按钮'
)
}
}
</script>
使用新组件的时候
// test.vue
<template>
<NewButton @click="click" />
</template>
<script>
import NewButton from "./Button";
export default {
components: { NewButton },
methods: {
click() {
console.log('一秒的防抖效果')
}
}
}
</script>
结果显示,高阶函数的运用,可以完美解决业务问题,不需要去改动源码重新打包等一系列操作。
四、总结
高阶函数作为一种进阶用法,在实际业务场景中,其实也是比较常用的,只是我们在学习的过程中,习惯了使用工具,而不是挖掘为什么能这么用,典型的知其然而不知其所以然,这是开发者常态了。
今天文章记录,也是我个人技术生涯上的又一次成长,希望我的个人知识能够帮助大家更好的了解高阶函数的这个概念和应用场景。