antdv4.0 官方组件库没有一个卡片式选择器的组件,于是我尝试自己封装了一个基于a-card组件的卡片式选择器组件。使用的是阿里的ant-design-vue4.0版本组件。
1. 需求
一个基于antdv4.0组件库a-card组件设计的卡片式的选择器组件,可以用于选择一个卡片选项,并且可以自定义选项内容包括图标和文字。antdv 组件详细使用查看antdv官方文档。
2. 设计
2.1 组件说明
这是一个卡片式选择器组件,可以通过单击选中一个卡片,被选中卡片会添加阴影及高亮效果。
该组件的原生是a-card组件,通过antdv的a-row及a-col组件进行布局。
2.2 使用
使用组件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| <template> <card-selector ref="cardRef" v-model:selectedCard="selectedCard" :cards="cards" > <template #icon="{ card }"> <BankOutlined/> </template> <template #title="{ card }"> {{ card }} </template> <template #content="{ card }"> <div :class="['center',{'blue-font': card == selectedCard}]"> {{card}} </div> <div class="center"> <a-tooltip placement="bottom"> <template #title>prompt text</template> <ExclamationCircleOutlined /> </a-tooltip> </div> </template> </card-selector> </template>
<script setup lang="ts"> import CardSelector from '#/CardSelector/index.vue' import { ref } from 'vue' import { BankOutlined, ExclamationCircleOutlined, } from '@ant-design/icons-vue'
const cards = ['Card A', 'Card B', 'Card C','Card D', 'Card E', 'Card F']; const selectedCard = ref(); </script>
<style lang="less" scoped>
.blue-font { color: #0a6efa; } </style>
|
2.3 组件接口
详细代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| <template> <div> <a-row :gutter="[16, 8]"> <a-col :span="6" v-for="(card, index) in props.cards" :key="index" > <a-card class="center" :class="{ 'shadow-[0_4px_20px_-5px_rgba(0,0,0,0.35)]': card === props.selectedCard, 'blue-border': card === props.selectedCard, }" @click="selectCard(card)" hoverable > <div class="icon center"> <slot name="icon" :card="card"></slot> </div> <div class="center"> <slot name="content" :card="card"></slot> </div> </a-card> <div class="centert" :class="{'blue-font': card === props.selectedCard}"> <slot name="title" :card="card" ></slot> </div> </a-col> </a-row> </div> </template>
<script setup lang="ts"> interface Props { cards: string[]; selectedCard: string; }
const props = defineProps<Props>();
const emit = defineEmits(['update:selectedCard']);
function selectCard(card: string) { emit('update:selectedCard', card); } </script>
<style lang="less" scoped>
.center { justify-content: center; display: flex; align-items: center; flex-direction: column; }
.icon { font-size: 30px; }
:deep(.ant-card-body) { padding: 12px; }
.blue-border { border: 1px solid #0a6efa; }
.blue-font { color: #0a6efa; } </style>
|