通过高阶组件抽离FormItem逻辑
高阶组件
- HOC: Higher Order Component: 高阶组件
 - 通过一个包装函数,包装一个子组件,然后再返回
 - 不关心包装的子组件是什么,只是为包装的子组件增加一个能力。
 - 这样如果以后增加能力修改了,也不影响包装的子组件,形成解耦
 - 这个和组合API的逻辑抽离有些差别,组合API只能抽离非渲染部分的逻辑,而高阶组件可以抽离渲染部分的逻辑
 - 有些问题:
- 问题:包装函数的props,要应用于所有的子组件,但是有些子组件的
props声明可能会不一样。 - 解决:可以在子组件上使用使用
attrs,这样未声明的props会被当做attrs传入。 - 问题:如果包装函数的组件有
slots也需要传递给子组件 - 解决:通过
<Component :slots="slots">解决 - 问题:ref的问题,通过ref获取到的只是包装函数的组件,无法获取到子组件的实例
 - 解决:没有办法解决
 
 - 问题:包装函数的props,要应用于所有的子组件,但是有些子组件的
 
//包装组件
const FormItem = defineComponent({
  name: 'FormItem',
  props: CommonWidgetPropsDefine,
  setup(props, { slots }) {
    const classesRef = useStyles()
    return () => {
      const classes = classesRef.value
      return (
        <div class={classes.container}>
        
        </div>
      )
    }
  },
})
// HOC: Higher Order Component: 高阶组件
export function withFormItem(Widget: any){
   return defineComponent({
    name: `Wrapped${Widget.name}`,
      props:CommonWidgetPropsDefine,
      setup(props,{slots,attrs}){
         return ()=>{
            return <FormItem {...props}>
                <Widget {...props} slots={slots} {...attrs} ></Widget>
            </FormItem>
         }
      }
   }) as any
}
//子组件
import { withFormItem } from './FormItem'
const TextWidget: CommonWidgetDefine = withFormItem(
  defineComponent({
    name: 'TextWidget',
    props: CommonWidgetPropsDefine,
    setup(props) {
      return () => {
        return (
          <input
            type="text"
            value={props.value as any}
            onInput={handleChange}
            style={styleRef.value}
          />
        )
      }
    },
  }),
)