使用VNode扩展相对复杂的Select组件

447 阅读2分钟

介绍

Select组件是日常开发中比较常见的组件,通常它是通过Options数组循环下拉选项。选项通常包含一个选项文本和一个选项值,如:{label:'',value:''}。我们假设业务中需要一个下拉组件,选项内容为一系列字体选项,我们期望选择对应选项改变某快业务的字体。

常规操作

初始要求很简单,通常我们都会使用一套UI组件库,如:ant-design-vue。此时我们快速的引入了Select组件。 carbon (57).png 我们为组件定义了数据源options,通过循环options渲染了a-select组件,并在组件选择某一个选项时将文本效果显示在class="show"的节点上,效果如下: 截屏2022-09-08 上午10.15.26.png

优化操作

从上图中看到,下拉选项是单纯的文字选项,它并不能直观的展现选项字体的效果,我们需要节点class=“show”来展示对应的字体效果。那么如何让选项直接展示字体效果呢?有的同学会说,我们直接循环的时候添加一个节点,设置对应的style就可以了,如下: carbon (55).png

截屏2022-09-08 上午11.35.54.png

我们将节点class=“show”,移动到a-select-option中,完美的解决了我们的需求。

一些思考

我们前面解决了组件的优化工作,然而上述的代码却不够灵活。你可能还会遇到以下情况:

  • 比方说你下次下拉选项要换成字体大小,此时你要在template上修改节点style为fontSize。
  • 又或者某一天你的下拉选项就是只显示纯文本,此时需要删除节点style
  • 一部分情况下,你可能需要使用<component :is=""></component>渲染动态组件,组件可能是select选项,也可能是radio选项,此时已经不是前面在template中修改dom可以解决的了

最终优化方式

我们知道,vue组件实际就是vnode对象,vue通过解析vode最后得到我们想要的dom树。我们可以通过vnode解决上面一些思考点。

我们创建一个组件,组件接受一个vnode,通过render函数渲染: carbon (49).png 此时template变为: carbon (54).png 我们引入了RenderVNode组件,并将option替换成该组件。当我们想自定义option时,只需要修改数据源即可。

我们将原有数据进行转换: carbon (51).png 通过map循环,我们将label值通过h函数转换成vnode节点,此时组件就可以正常渲染文本选项或者自定义选项了。最终代码: carbon (52).png