高阶组件的特点和高阶函数类似,高阶函数接受一个/多个函数作为参数,返回另一个函数,高阶组件则是组件作为参数,返回另外一个组件。只要满足其中2个条件之一即可。
高阶组件在一些场景下可以对组件进行复用,增强组件功能,控制渲染的内容。
在 Vue 里创建高阶组件:
// pageA.vue
<script>
export default {
name: 'PageA',
template: '<div>pageA</div>'
}
</script>
// login.vue
<script>
export default {
name: 'Login',
template: '<div>login</div>'
}
</script>
// auth.js
import PageLogin from './page/login'
function getToken() {
return 'token'
}
function auth(component) {
return {
props: component.props,
render(h) {
if (getToken()) {
const slots = Object.keys(this.$slots).reduce(
(arr, key) => arr.concat(this.$slots[key]),
[]
)
return h(
component,
{
props: this.$props,
attrs: this.$attrs,
on: this.$listeners
},
slots
)
} else {
return h(PageLogin)
}
}
}
}
// 使用
import auth from './auth'
import pageA from './page/pageA.vue
// 需要验证的时候调用auth函数就能实现页面鉴权,pageA页面无需修改任何东西
const AuthPageA = auth(PageA)
export default {
components: {
AuthPageA
}
}
// list.vue
import getProducts from '../api'
export default {
props: {
type: String
},
data () {
return {
products: []
}
},
template: '<div>list</div>',
mounted () {
getProducts(this.type).then(products => {
this.products = products
})
}
}
// createList.js
import List from './list'
export default function createList (type) {
return {
render (h) {
return h(List, { props: { type } })
}
}
}
// 使用:
// 创建一个销售列表
export default createList('sales')
// 创建一个互换商品列表
export default createList('swap')
Vue 里使用 HOC 没有 React 里用得那么灵活,React 大部分时候是写函数,和高阶组件的契合度高。Vue 里如果不用高阶组件,也可以用 mixins 、组件嵌套的方式来解决这些问题,具体方式根据实际业务场景选择。