card组件在我们日常开发中经常使用,如果能够有一个较好的封装,将会省去很多的重复代码,提高开发效率。
card 组件需要实现哪些功能呢
必须分为标题和内容两部分,并且都支持自定义
要与cardGroup相结合能够实现水平排列和垂直排列,或者瀑布流排列
能够自定义背景色
提供一种或多种hover特效
card提供点击事件用以交互
<template>
<div
@click="cardClick"
class="dx-card-warpper"
:class="hover"
:style="background ? { background } : {}"
>
<div class="dx-card-title" v-if="showTitle">
<slot name="title" />
</div>
<div class="dx-card-title dx-card-title-default" v-else-if="title">
<span class="dx-card-title-default-text">
{{ title }}
</span>
</div>
<div class="dx-card-content">
<slot />
</div>
</div>
</template>
<script lang="ts">
import { ComponentInternalInstance, getCurrentInstance, ref, PropType } from 'vue'
export default {
props: {
title: {
required: false,
default: '',
type: String
},
hover: {
required: false,
default: '',
type: String as PropType<'boxShadow' | 'floatUp' | 'enlarge'>
},
background: {
required: false,
default: '',
type: String
}
},
setup() {
const currentInstance: ComponentInternalInstance | null = getCurrentInstance()
const cardClick = function (e: Event) {
currentInstance?.emit('click', e)
}
// 自定义card头部
const showTitle = ref(false)
const title = currentInstance?.slots.title
if (title) {
showTitle.value = true
}
return {
cardClick,
showTitle
}
}
}
</script>
<style lang="scss" scoped>
@import '@/scss/layout.scss';
.dx-card-warpper {
border-radius: 4px;
border: $border;
cursor: pointer;
width: 100%;
.dx-card-title {
border-bottom: $border;
padding: 24px;
}
.dx-card-title-default {
font-size: 16px;
font-weight: 600;
display: flex;
}
.dx-card-content {
padding: 24px;
}
}
.dx-card-warpper.boxShadow:hover {
box-shadow: 4px 4px 10px rgb(0 0 0 / 29%);
}
.dx-card-warpper.floatUp:hover {
transform: translateY(-10%);
}
.dx-card-warpper.enlarge:hover {
transform: scale(1.1);
}
</style>
cardgroup组件
<template>
<div class="dx-card-group-warpper" :class="ClassName" ref="cardGroup">
<slot />
</div>
</template>
<script lang="ts">
import { ref, onMounted } from 'vue'
import { Data } from '../dialog/types'
export default {
props: {
// columnNumber表示每行有多少列
columnNumber: {
required: false,
default: 1,
type: Number
}
},
setup(propsData: Data) {
// 自定义card头部
const cardGroup: any = ref(null)
const ClassName = `count-number-${propsData.columnNumber}`
const flowClassName = onMounted(() => {
// ref只能在onMounted里面才能获取
const hasNotCardComponents = [...cardGroup.value.children].some((item: any) => {
return item.className !== 'dx-card-warpper'
})
if (hasNotCardComponents) {
// 算是给开发者的题型,在CardGroup里只能使用card组件
console.log(Error('Only Card components can be used in CardGroup'))
}
})
return {
cardGroup,
ClassName
}
}
}
</script>
<style lang="scss" scoped>
@import '@/scss/layout.scss';
.dx-card-group-warpper {
width: 100%;
display: flex;
flex-wrap: wrap;
align-items: stretch;
::v-deep .dx-card-warpper {
margin-bottom: 12px;
}
}
@for $i from 2 through 99 {
.count-number-#{$i} {
// gap: calc(4% / #{$i - 1});
::v-deep .dx-card-warpper {
width: calc(96% / #{$i});
margin-right: calc(4% / #{$i - 1});
}
::v-deep .dx-card-warpper:nth-child(#{$i}n + #{$i}) {
margin-right: 0 !important;
}
}
}
</style>
与cardgroup组件一起使用
<CardGroup :columnNumber="3">
<Card>Hover</Card>
<Card>Hover</Card>
<Card :title="3">Hover</Card>
<Card :title="3">Hover</Card>
</CardGroup>

提供了线上的体验网站,欢迎大家前来,并提出你的建议
http://www.dxyx-together.cn/#/card