121 lines
2.8 KiB
Vue
121 lines
2.8 KiB
Vue
<template>
|
||
<!-- 完全自定义卡片容器,复刻el-card样式 -->
|
||
<div
|
||
class="el-card custom-card"
|
||
:style="{ width: width || '100%' }"
|
||
v-bind="$attrs"
|
||
v-on="$listeners"
|
||
>
|
||
<!-- 卡片头部 - 独立节点 -->
|
||
<div v-if="$slots.header" class="el-card__header card-header">
|
||
<slot name="header"></slot>
|
||
</div>
|
||
|
||
<!-- 可滚动内容区域 - 独立节点 -->
|
||
<div class="el-card__body card-body">
|
||
<slot></slot>
|
||
</div>
|
||
|
||
<!-- 卡片底部 - 独立节点 -->
|
||
<div v-if="$slots.footer" class="el-card__footer card-footer">
|
||
<slot name="footer"></slot>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
module.exports = {
|
||
name: 'CustomCard',
|
||
inheritAttrs: false,
|
||
props: {
|
||
// 保留el-card的核心属性,保证使用体验一致
|
||
width: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
shadow: {
|
||
type: String,
|
||
default: 'hover', // 同el-card默认值
|
||
validator: (val) => ['always', 'hover', 'never'].includes(val)
|
||
}
|
||
},
|
||
computed: {
|
||
// 根据shadow属性动态设置阴影样式
|
||
shadowClass() {
|
||
return {
|
||
'el-card--shadow-always': this.shadow === 'always',
|
||
'el-card--shadow-hover': this.shadow === 'hover',
|
||
'el-card--shadow-never': this.shadow === 'never'
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
/* 卡片核心样式 - 完全复刻el-card */
|
||
.custom-card {
|
||
display: flex;
|
||
flex-direction: column;
|
||
height: calc(100vh - 84px); /* 关键:卡片高度撑满父容器 */
|
||
background: #fff;
|
||
border-radius: 4px;
|
||
box-sizing: border-box;
|
||
margin: 0;
|
||
border: 0;
|
||
/* 继承el-card的字体样式 */
|
||
color: var(--el-text-color-primary);
|
||
font-size: 14px;
|
||
transition: box-shadow 0.3s ease-in-out;
|
||
overflow: hidden;
|
||
}
|
||
|
||
/* 阴影样式 - 完全对齐el-card */
|
||
:deep(.el-card--shadow-always) {
|
||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||
}
|
||
:deep(.el-card--shadow-hover):hover {
|
||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||
}
|
||
:deep(.el-card--shadow-never) {
|
||
box-shadow: none;
|
||
}
|
||
|
||
/* 头部样式 - 固定高度,不滚动 */
|
||
.card-header {
|
||
flex-shrink: 0; /* 关键:不被压缩 */
|
||
padding: 18px 20px;
|
||
border-bottom: 1px solid #ebeef5;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
/* 内容区域 - 自动填充剩余空间,可滚动 */
|
||
.card-body {
|
||
flex: 1; /* 关键:占满剩余高度 */
|
||
padding: 20px;
|
||
overflow-y: auto; /* 垂直滚动 */
|
||
overflow-x: hidden; /* 隐藏水平滚动 */
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
/* 底部样式 - 固定高度,不滚动 */
|
||
.card-footer {
|
||
flex-shrink: 0; /* 关键:不被压缩 */
|
||
padding: 18px 20px;
|
||
border-top: 1px solid #ebeef5;
|
||
box-sizing: border-box;
|
||
text-align: right;
|
||
}
|
||
|
||
/* 兼容el-card的默认样式覆盖 */
|
||
:deep(.el-card__header) {
|
||
padding: 0;
|
||
margin: 0;
|
||
border: 0;
|
||
}
|
||
:deep(.el-card__body) {
|
||
padding: 0;
|
||
margin: 0;
|
||
}
|
||
</style>
|