Descriptions 描述列表怎么动态控制显示项?
我用 Ant Design 的 Descriptions 组件展示用户信息,但有些字段可能为空,不想显示整行。试过在 Descriptions.Item 外面包条件判断,但页面布局会错乱,有没有推荐的写法?
比如下面这样写,空字段虽然不渲染了,但 Description 的列对齐就乱了:
<a-descriptions :column="2">
<a-descriptions-item label="姓名">{{ name }}</a-descriptions-item>
<template v-if="phone">
<a-descriptions-item label="电话">{{ phone }}</a-descriptions-item>
</template>
<template v-if="email">
<a-descriptions-item label="邮箱">{{ email }}</a-descriptions-item>
</template>
</a-descriptions>
说下为什么会乱。Descriptions 内部是用 grid 布局或者 table 布局来计算的,当你设置 column="2" 时,它预期每行有两个单元格。你用 v-if 干掉一个,后面的元素就往前挤,label 和值就对不上了。
正确的做法是不要在模板里写条件判断,而是把数据结构化,在 JS 层面过滤掉空值,然后统一循环渲染。
给你一个完整的写法:
这样写的好处是 Descriptions 拿到的永远是一份"干净"的数据,它只管渲染,不需要管哪些要显示哪些要隐藏,布局计算就不会出问题。
需要注意一点,如果你的数据是异步获取的,要确保在数据加载完成后再渲染 Descriptions,不然初始化时全是空的,后面数据来了也不会重新计算布局。可以加个 v-if 判断:
还有一种情况,如果你希望某个字段即使为空也占位(保持布局整齐),可以稍微改下过滤逻辑,给空值一个默认显示文本:
这样所有字段都会显示,空值显示 "--",布局也不会乱。看你具体需求选哪种方案。
直接说原因:Descriptions 组件是按行列布局计算的,你用
v-if把某个 Item 干掉了,它那一行的格子数就不够了,后面的元素会补上来,列对齐自然就炸了。最稳妥的方案是用
computed先把数据过滤好,然后用v-for渲染,这样 Ant Design 内部计算布局时拿到的是干净的列表,不会出问题。给你个我项目里用的写法:
这样写有几个好处:一是布局永远不会乱,因为传给组件的就是过滤后的数据;二是后续维护方便,要加字段直接往
allItems数组里塞就行。还有个小技巧,如果你的空值判断逻辑比较复杂,比如还要判断空数组、空对象之类的,可以单独抽一个工具函数出来复用。