Open AnnVoV opened 6 years ago
比如我们要把一个ajax获取数据的功能放到一个高阶组件里
// APILoader.js // 首先高阶函数的意思就是通过一个函数,传入一个函数,得到另一个函数So import api from 'component/api' import React from 'react' function AjaxLoader() { // 首先这里要返回个函数 return function(MyComponent) { class APILoader extends React.Component { constructor(props) { super(props) this.state = { ajaxData: {} } } componentDidMount() { // 异步加载数据 api.then((data)=> { this.setState({ ajaxData: data }) }) } render() { return ( <MyComponent data={this.state.ajaxData}/> ) } } return APILoader } } export default AjaxLoader;
// BookLoader.js import APILoader from './APILoader' import React from 'react' class Book extends React.Component { constructor(props) { super(props) } render() { const {name, author} = this.props; return ( <section> <div>{name}</div> <div>{author}</div> </section> ) } } export default APILoader()(Book)
![IMAGE](quiver-image-url/1B82D7CF4D0F1E8308C7CB963525AC1F.jpg =652x309)
在mixin中,组件和mixin之间是相互感知的。基于在多个mixin同时作用于一个组件上时,mixin之间也可能相互影响。这个就像复杂的多角恋关系。
在HOC中,组件对包裹自己的HOC毫不知情,只知道接受自己想要的props,可以单纯地作自己组件份内的事情。要给组件附加的特定逻辑(包括props、methods、computed等),都在HOC中实现和管理。HOC更像是一个暗恋者,默默地为组件做了一些事情,组件却不知道(也没必要知道)。
ps: 关于slot 的部分如何解决,我还没有搞明白。。。 vue 中一般我们都用Mixin,那在Vue中如何实现HOC组件呢?(vue中hoc的实现依赖于render函数,先回顾下render函数)
{ // v-bind: class 'class': { foo: true, bar: false }, // v-bind: style style: { color: 'red', fontSize: '14px' }, // 正常的HTML特性 attrs: { id: 'foo' }, // 组件props props: { myProp: 'bar' }, // DOM属性 domProps: { innerHTML: 'baz' }, // 事件监听基于on on: { click: this.clickHandler } // 自定义指令 directives: [ { name: 'my-custom-directive', value: '2', expression: '1 + 1', arg: 'foo', modifiers: { bar: true } } ] // 作用域插槽 // { name: props => VNode | Array<VNode> } scopedSlots: { default:props => createElement('span', props.text) }, // 如果组件是其他组件的子组件,需为插槽指定名称 slot: 'name-of-slot', // 其他特殊顶层属性 key: 'myKey', ref: 'myRef' }
import Ajax from 'api/ajax'; const hoc = (component) => { // component 上的props const inheritedProps = component.props || []; return { render(createElement) { return createElement(component, { props: { ...inheritedProps, data: this.fetchedData } }) }, // hoc 的props和component保持一致 props: [...inheritedProps], data() { return { fetchedData: {} } }, mounted() { Ajax.get('/user/getUserInfo') .then((data) => { this.fetchedData = data; }); } } } export default hoc;
<template> <div> <span>name:{{data}}</span> <button>click</button> </div> </template> <script> export default { props: ['url', 'data'], mounted() { console.log('来自baseComp的mounted'); } } </script>
import hoc from './hoc'; import BaseComp from './baseComp' export default { ... components: { 'enhance-comp': hoc(BaseComp) } }
http://hcysun.me/2018/01/05/%E6%8E%A2%E7%B4%A2Vue%E9%AB%98%E9%98%B6%E7%BB%84%E4%BB%B6/
HOC 组件的特点
React 中的高阶函数(High Order Component)
比如我们要把一个ajax获取数据的功能放到一个高阶组件里
mixin 与 HOC 对比
![IMAGE](quiver-image-url/1B82D7CF4D0F1E8308C7CB963525AC1F.jpg =652x309)
在mixin中,组件和mixin之间是相互感知的。基于在多个mixin同时作用于一个组件上时,mixin之间也可能相互影响。这个就像复杂的多角恋关系。
在HOC中,组件对包裹自己的HOC毫不知情,只知道接受自己想要的props,可以单纯地作自己组件份内的事情。要给组件附加的特定逻辑(包括props、methods、computed等),都在HOC中实现和管理。HOC更像是一个暗恋者,默默地为组件做了一些事情,组件却不知道(也没必要知道)。
Vue中如何实现HOC
ps: 关于slot 的部分如何解决,我还没有搞明白。。。 vue 中一般我们都用Mixin,那在Vue中如何实现HOC组件呢?(vue中hoc的实现依赖于render函数,先回顾下render函数)
render函数中的Vnode数据对象
hoc组件
baseComponent组件
app.js
深入阅读资料:
http://hcysun.me/2018/01/05/%E6%8E%A2%E7%B4%A2Vue%E9%AB%98%E9%98%B6%E7%BB%84%E4%BB%B6/