【紧贴业务,拿来即用】真的嘛?一个组件能渲染出 element 各种组件

87 阅读1分钟

我正在参加「掘金·启航计划」

需求

image.png 经常遇到封装业务组件,某个区域情况1为input、情况2为select,下次需求又有情况3、4...,就得在组件内部兼容 --- 维护者不爽

此刻,你可能会说用插槽,那么每个情况都得有个不同 name 的模板 --- 使用者不爽

分析

其实发现这种需求一般是,情况多并且对应渲染不同组件,不需要太多针对具体组件的处理,支持双向绑定 v-model 就能满足大多数需求,配置也不会太复杂;当然渲染组件的 props、事件、插槽都支持,复杂场景也能应对

思路

采用更加灵活的 render 函数搭配 jsx 语法实现

  • 目录结构

    render
        slots
            el-input.js
            el-select.js
            ...
        index.js
    
  • index.js(动态渲染不同组件,根据配置解析 props、事件、插槽使其生效)

    • config(定义渲染的组件)
    {
        tag:组件名
        __slot__:可配置对应 slots 文件夹下指定组件文件中定义的 key
        __attrs__:element 组件支持的配置
        on: 组件事件
        nativeOn:组件原生事件
    }
    
    • slots 渲染
      • 默认会读取 slots 文件夹所有文件内容,转换为对象
      • 基于 config.tag 匹配处理文件
      • 基于 conifg._slot_ 调用相关函数获取插槽内容
  • slots.el-select.js

    export default {
       // 渲染默认插槽,常见只有 el-option
      options(h, conf) {
        const list = []
        conf.__slot__.options.forEach((item) => {
          list.push(<el-option label={item.label} value={item.value} disabled={item.disabled}></el-option>)
        })
        return list
      },
      // Select 组件头部内容
      prefix(h, conf, key) {
        return <template slot="prefix">{typeof conf.__slot__[key] === 'function' ? conf.__slot__[key]() : conf.__slot__[key]}</template>
      },
      // 无选项时的列表
      empty(h, conf, key) {
        return <template slot="empty">{typeof conf.__slot__[key] === 'function' ? conf.__slot__[key]() : conf.__slot__[key]}</template>
      },
    }
    

体验

借鉴

form-generator

希望看完的朋友可以点个喜欢/关注,您的支持是对我最大的鼓励