请花15秒观察下图,后续将对部分 UI 实现组件化:
通过分析以上UI图,可以发现“我的家人”、“家庭必备保障” 的UI 具有很强的相似性。
于是,我打算将这块封装成一个组件,名为 ItemBoard.vue(项目面板),对应下图绿色框。
这个组件可配置的地方就在于面板标题和包含的列表项。可见,传给该组件的数据便是一个标题字符串和一个数组,我将这两个数据作为它的props传进来。它承担的UI功能是遍历展示列表项,并决定列表项间的间距,以及是否需要在列表项下面显示一条细线。
为了灵活性考虑,我将单个列表项也封装成了一个组件,名为 Item.vue,对应上图的红色框。该组件的UI可以分成左右两部分,如上图黑线分隔。左边部分对于所有用例来说都是完全一样的:头像、名称、描述。唯独右边部分有的是文字,有的是箭头>,有的是垃圾桶图标。所以,该组件的右侧具体显示成什么,应该由使用 Item 的组件来决定,即由 ItemBoard 决定。Vue 提供了 slot 语法让父组件向子组件传递 UI 内容。
Item.vue UI实现大致为:
<template>
<div class="left”>…...</div>
<div class=“right”>
<slot name=“right”></slot>
</div>
</template>
现在问题来了,ItemBoard 作为一个通用组件,它真的知道应该给 Item 的 right slot 传什么 UI 成分吗?
它其实是不知道的,因为具体传什么 UI 成分取决于 ItemBoard 展现的是什么数据。如果展现的是1号区块,那么应该根据列表数据的保单数展示文字;如果展现的是2号区块,那么应该全部展示右箭头(>)。。。
此时,似乎不得不把具体展现什么UI的逻辑写在 ItemBoard 中了,通过传入的数据告诉 ItemBoard 具体展现的是几号区块,然后 ItemBoard 决定展现什么 UI 给 Item。但是,这样一来,ItemBoard 的展现就和它的数据紧密耦合了,要是以后列表项的右侧部分又多了一种 UI,那么不得不修改 ItemBoard 的代码以满足新增的需求。
我对 React 也有接触。在 React 中,这种情况很好解决,JSX语法使得将看起来像组件声明式的组件实例作为数据放在 JS 对象中。如
{
title: ‘’,
desc: ‘’,
rightComponent: <Delete />
}
这样的话,ItemBoard 只需要取传入数据的 rightComponent 属性便可以了。将具体展现什么的任务交给了注入的数据,具有很大的灵活性。
所以,我的问题就是, Vue 对于这种情况应该如何处理?
我的问题在知乎上得到了解答和解决:
使用scoped slot语法
https://www.zhihu.com/questio...