我正在参加「掘金·启航计划」
需求
经常遇到封装业务组件,某个区域情况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> }, }
体验
借鉴
希望看完的朋友可以点个喜欢/关注,您的支持是对我最大的鼓励