el-table的第二列el-table-column右侧边框加粗
时间: 2023-11-07 07:03:08 浏览: 195
.el-table-column的右侧边框可以通过添加以下CSS样式来加粗:
.el-table .el-table__body-wrapper .cell:nth-child(2) {
border-right-width: 2px;
border-right-style: solid;
}
相关问题
el-table表格整体边框加粗
### 如何在 Element UI 的 el-table 组件中设置表格整体边框加粗
在 Element UI 中,`<el-table>` 的样式可以通过自定义 CSS 进行调整。为了实现 `<el-table>` 表格的整体边框加粗效果,可以针对 `.el-table--border` 类进行样式覆盖[^1]。以下是具体的实现方法和代码示例:
#### 1. 自定义表格整体边框样式
通过使用 `::v-deep` 或 `/deep/` 深度选择器(根据 Vue 版本和项目配置选择),可以直接修改 `<el-table>` 的边框样式。以下是一个完整的 CSS 示例:
```css
/* 设置表格整体边框加粗 */
/deep/ .el-table--border, /deep/ .el-table--group {
border: 2px solid #000; /* 设置边框宽度为 2px,颜色为黑色 */
}
/* 设置单元格的边框加粗 */
/deep/ .el-table td.el-table__cell, /deep/ .el-table th.el-table__cell.is-leaf {
border: 2px solid #000; /* 单元格边框宽度为 2px,颜色为黑色 */
}
/* 清除多余的边框线(可选) */
/deep/ .el-table--border::after, /deep/ .el-table--group::after, /deep/ .el-table::before {
background-color: transparent !important; /* 避免出现多余的虚线或背景色 */
}
```
#### 2. 在 Vue 项目中应用样式
将上述样式添加到项目的全局样式文件(如 `src/assets/styles/global.css`)或组件的 `<style scoped>` 中。如果使用的是 Vue 2 和 Scoped CSS,则需要使用 `/deep/` 深度选择器来穿透作用域限制[^3]。
#### 3. 注意事项
- 如果项目中启用了 Scoped CSS,必须使用 `/deep/` 或 `::v-deep` 来确保样式能够正确应用于子组件。
- 确保样式优先级足够高,可以通过添加 `!important` 提升优先级[^2]。
- 调整边框颜色时,建议与项目整体设计风格保持一致。
#### 示例代码
以下是一个完整的 Vue 组件示例,展示如何应用上述样式:
```vue
<template>
<el-table :data="tableData" style="width: 100%" border>
<el-table-column prop="date" label="日期" width="180"></el-table-column>
<el-table-column prop="name" label="姓名" width="180"></el-table-column>
<el-table-column prop="address" label="地址"></el-table-column>
</el-table>
</template>
<script>
export default {
data() {
return {
tableData: [
{ date: "2023-01-01", name: "张三", address: "北京市" },
{ date: "2023-01-02", name: "李四", address: "上海市" },
],
};
},
};
</script>
<style scoped>
/* 使用深度选择器 */
/deep/ .el-table--border, /deep/ .el-table--group {
border: 2px solid #000;
}
/deep/ .el-table td.el-table__cell, /deep/ .el-table th.el-table__cell.is-leaf {
border: 2px solid #000;
}
</style>
```
---
<template> <div class="detail-container"> <!-- 索引板块卡片 --> <el-card class="index-card"> <!-- 表单区域 --> <el-form :model="formData" label-position="top" ref="indexForm" class="mobile-form" > <!-- 问卷标题 --> <el-form-item label="问卷标题:" prop="dcWjTitle"> <el-input v-model="formData.dcWjTitle" placeholder="请输入问卷标题" clearable :prefix-icon="Document" /> </el-form-item> <!-- 被测评人 --> <el-form-item label="被测评人:" prop="dcId"> <el-select v-model="formData.dcId" multiple filterable remote reserve-keyword clearable placeholder="请选择被测评人" :remote-method="searchBdr" :loading="bdrLoading" @focus="handleBdrFocus" style="width: 100%" > <el-option v-for="item in bdrOptions" :key="item.dcId" :label="item.dcName" :value="item.dcId" /> </el-select> </el-form-item> <!-- 人员部门 --> <el-form-item label="人员部门:" prop="dcDept"> <el-input v-model="formData.dcDept" placeholder="请输入人员部门" clearable :prefix-icon="OfficeBuilding" /> </el-form-item> <!-- 提交状态 --> <el-form-item label="提交状态:" prop="state"> <el-select v-model="formData.state" placeholder="请选择提交状态" clearable class="mobile-select" > <el-option label="已提交" :value="1" /> <el-option label="未提交" :value="0" /> </el-select> </el-form-item> <!-- 新增:按钮区域 --> <el-form-item class="button-group"> <el-button type="primary" @click="handleSearch" class="action-button" :icon="Search" > 搜索 </el-button> <el-button @click="handleReset" class="action-button" :icon="Refresh" > 重置 </el-button> </el-form-item> </el-form> </el-card> <!-- 数据显示板块 --> <el-card class="data-card"> <!-- 刷新数据 --> <template #header> <div class="card-header"> <el-button type="primary" size="small" :icon="Refresh" @click="fetchData" > 刷新数据 </el-button> </div> </template> <!-- 数据表格 --> <el-table :data="tableData" v-loading="loading" element-loading-text="数据加载中..." stripe style="width: 100%" class="mobile-table" > <el-table-column prop="dcWjId" label="序号" width="120" /> <el-table-column prop="dcWjTitle" label="问卷标题" min-width="150" /> <el-table-column prop="dcName" label="被测评人" width="120" /> <el-table-column prop="dcDept" label="部门" width="120" /> <el-table-column prop="state" label="提交状态" width="100"> <template #default="scope"> <el-tag :type="scope.row.state === '1' ? 'success' : 'info'"> {{ scope.row.state === '1' ? '已提交' : '未提交' }} </el-tag> </template> </el-table-column> <el-table-column prop="score" label="总分" width="120" /> <el-table-column prop="createTime" label="创建时间" width="180" /> <el-table-column prop="updateTime" label="提交时间" width="180" /> <el-table-column label="操作" width="120" fixed="right"> <template #default="scope"> <el-button size="small" type="primary" @click="handleView(scope.row)" > 编辑/查看 </el-button> </template> </el-table-column> </el-table> <!-- 分页控件 --> <div class="pagination-container"> <el-pagination v-model:current-page="pagination.current" v-model:page-size="pagination.size" :page-sizes="[5, 10, 20, 50]" layout="total, sizes, prev, pager, next, jumper" :total="pagination.total" @size-change="handleSizeChange" @current-change="handlePageChange" /> </div> </el-card> </div> </template> <script setup> // 确保正确导入所有 Vue 函数 import { ref, reactive, onMounted, onUnmounted } from 'vue'; import axios from 'axios'; import { Document, User, OfficeBuilding, Search, Refresh } from '@element-plus/icons-vue'; import { ElMessage } from 'element-plus'; import { useRouter } from 'vue-router'; const router = useRouter(); // 环境变量管理API地址 const API_BASE = import.meta.env.VITE_API_BASE || 'http://172.26.26.43/dev-api'; const API_URL = `${API_BASE}/wjdc/wj/listTx`; const BDR_API_URL = `${API_BASE}/wjdc/wj/getBdrList`; // 被测评人相关数据 const bdrOptions = ref([]); // 被测评人选项列表 const bdrLoading = ref(false); // 加载状态 const bdrCache = ref([]); // 缓存所有被测评人数据 // 表单数据 const formData = reactive({ dcWjTitle: '', dcId: [], dcDept: '', state: null }); // 表格数据 const tableData = ref([]); const loading = ref(false); // 分页配置 const pagination = reactive({ current: 1, size: 10, total: 0 }); // 表单引用 const indexForm = ref(null); // 请求取消令牌 let cancelTokenSource = axios.CancelToken.source(); // 处理被测评人输入框获取焦点 const handleBdrFocus = () => { if (bdrCache.value.length === 0) { fetchBdrList(''); } }; // 获取被测评人列表 const fetchBdrList = async (keyword = '') => { const token = getAuthToken(); if (!token) return; bdrLoading.value = true; try { const response = await axios.get(BDR_API_URL, { headers: { 'Authorization': `Bearer ${token}` } }); // 判断返回的数据是否是数组 if (Array.isArray(response.data)) { // 缓存所有数据 bdrCache.value = response.data; // 根据关键字过滤 if (keyword) { const searchTerm = keyword.toLowerCase(); bdrOptions.value = bdrCache.value.filter(item => item.dcName && item.dcName.toLowerCase().includes(searchTerm) ).slice(0, 10); // 最多显示10条 } else { // 未输入关键字时显示前10条 bdrOptions.value = bdrCache.value.slice(0, 10); } } else { // 如果不是数组,则按照原有格式处理(假设有code和data) if (response.data && response.data.code === 200) { bdrCache.value = response.data.data || []; // 同样的过滤逻辑 if (keyword) { const searchTerm = keyword.toLowerCase(); bdrOptions.value = bdrCache.value.filter(item => item.dcName.toLowerCase().includes(searchTerm) ).slice(0, 10); } else { bdrOptions.value = bdrCache.value.slice(0, 10); } } else { const msg = response.data?.msg || '返回数据格式不正确'; ElMessage.error('获取被测评人列表失败: ' + msg); } } } catch (error) { console.error('获取被测评人列表失败:', error); ElMessage.error('获取被测评人列表失败'); } finally { bdrLoading.value = false; } }; // 搜索被测评人(防抖) let searchBdrTimer = null; const searchBdr = (query) => { if (searchBdrTimer) clearTimeout(searchBdrTimer); searchBdrTimer = setTimeout(() => { if (bdrCache.value.length === 0) { fetchBdrList(query); } else { // 本地过滤 if (query) { const searchTerm = query.toLowerCase(); bdrOptions.value = bdrCache.value.filter(item => item.dcName.toLowerCase().includes(searchTerm) ).slice(0, 10); } else { bdrOptions.value = bdrCache.value.slice(0, 10); } } }, 300); }; // 获取认证令牌 const getAuthToken = () => { const token = localStorage.getItem('token'); if (!token) { ElMessage.warning('请先登录'); router.push('/login'); return null; } return token; }; // 搜索按钮处理函数 - 防抖 let searchTimer = null; const handleSearch = () => { // 检查被测评人选择数量 if (formData.dcId.length > 1) { ElMessage.warning({ message: '当前只能搜索一个被测人员', duration: 3000 }); return; } if (searchTimer) clearTimeout(searchTimer); searchTimer = setTimeout(() => { pagination.current = 1; fetchData(); }, 300); }; // 重置按钮处理函数 const handleReset = () => { if (indexForm.value) { indexForm.value.resetFields(); // 确保重置后 dcId 是空数组 formData.dcId = []; } handleSearch(); }; // 编辑/查看 const handleView = (row) => { router.push({ name: 'Operation', // 路由名称 params: { id: row.dcWjId // 传递问卷ID作为参数 } }); }; // 分页大小改变 const handleSizeChange = (size) => { pagination.size = size; fetchData(); }; // 页码改变 const handlePageChange = (page) => { pagination.current = page; fetchData(); }; // 获取数据 const fetchData = async () => { // 获取认证令牌 const token = getAuthToken(); if (!token) return; // 取消之前的请求 if (cancelTokenSource) { cancelTokenSource.cancel('请求被取消'); } cancelTokenSource = axios.CancelToken.source(); loading.value = true; try { // 构造请求参数 const params = { pageNum: pagination.current, pageSize: pagination.size, ...formData, // 安全处理:确保 dcId 是数组再 join dcId: Array.isArray(formData.dcId) ? formData.dcId.join(',') : '' // 将数组转换为逗号分隔的字符串 }; // 调用API - 添加认证头 const response = await axios.get(API_URL, { params, cancelToken: cancelTokenSource.token, headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` } }); // 处理响应数据 const { data } = response; if (data && data.code === 200) { // 修改点:直接使用 data.rows 和 data.total tableData.value = data.rows || []; pagination.total = data.total || 0; // 空数据提示 if (tableData.value.length === 0) { ElMessage.info('没有找到匹配的数据'); } } else { const errorMsg = data?.msg || '未知错误'; console.error('API返回错误:', errorMsg); ElMessage.error(`请求失败: ${errorMsg}`); tableData.value = []; pagination.total = 0; } } catch (error) { // 处理认证失败 if (error.response && error.response.status === 401) { ElMessage.error('认证过期,请重新登录'); localStorage.removeItem('token'); router.push('/login'); return; } // 忽略取消请求的错误 if (!axios.isCancel(error)) { console.error('获取数据失败:', error); const errorMsg = error.response?.data?.message || '网络请求失败'; ElMessage.error(`请求失败: ${errorMsg}`); tableData.value = []; pagination.total = 0; } } finally { loading.value = false; } }; // 页面加载时获取初始数据 onMounted(() => { fetchData(); }); // 组件卸载时取消所有请求 onUnmounted(() => { if (cancelTokenSource) { cancelTokenSource.cancel('组件卸载,取消请求'); } }); </script> <style scoped> /* 移动端适配样式 */ .detail-container { padding: 12px; } /* 添加选择器样式 */ :deep(.el-select) .el-input__inner { height: auto !important; min-height: 44px; padding: 5px 15px; } /* 标签样式 */ :deep(.el-tag) { margin: 2px 6px 2px 0; } /* 下拉菜单样式 */ :deep(.el-select-dropdown) { max-height: 300px; overflow-y: auto; } .index-card { border-radius: 12px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05); } .card-header { font-size: 18px; font-weight: 600; color: #1a1a1a; } .mobile-form { :deep(.el-form-item__label) { font-weight: 500; margin-bottom: 6px; } :deep(.el-input__inner) { height: 44px; border-radius: 8px; } } .mobile-select { width: 100%; :deep(.el-input__inner) { height: 44px; } } /* 按钮区域样式 */ .button-group { display: flex; gap: 12px; margin-top: 16px; } .action-button { flex: 1; height: 46px; font-size: 16px; border-radius: 8px; } /* 移动端响应式调整 */ @media (max-width: 480px) { .button-group { flex-direction: column; gap: 10px; } .action-button { width: 100%; } } </style> 我想要修改布局,把数据显示板块中通过接口获取的数据通过卡片方式显示,类似与之前的Operation问题的卡片布局样式,主要是适用于移动端,可以在该条数据卡片里,序号和问卷标题显示在卡片顶部,中间显示被测评人、部门、提交状态、总分、最下面显示创建时间和提交时间以及操作按钮
<think>我们将修改数据显示部分,将表格替换为卡片布局,每个卡片显示一条记录。
卡片结构设计如下:
顶部:序号和问卷标题(一行显示,序号和标题)
中间部分:被测评人、部门、提交状态、总分(分成两行,每行两个信息)
底部:创建时间、提交时间以及操作按钮(操作按钮放在最下面)
移动端适配:卡片宽度100%,并设置合适的间距。
修改步骤:
1. 移除原有的el-table,改为使用div和el-card来展示每一条数据。
2. 使用v-for循环tableData,为每一条数据生成一个卡片。
3. 在卡片内部按照要求布局。
注意:分页部分保持不变。
由于数据量可能较大,我们仍然保留分页功能。
同时,为了在移动端有更好的显示,我们将使用flex布局来排列中间部分的信息。
修改后的代码:</think>我将修改数据显示板块,将表格布局改为卡片布局,使其更适应移动端显示。以下是完整的解决方案:
```vue
<template>
<div class="detail-container">
<!-- 索引板块卡片 -->
<el-card class="index-card">
<!-- ...搜索表单保持不变... -->
</el-card>
<!-- 数据显示板块 -->
<el-card class="data-card">
<template #header>
<div class="card-header">
<el-button
type="primary"
size="small"
:icon="Refresh"
@click="fetchData"
>
刷新数据
</el-button>
</div>
</template>
<!-- 数据加载提示 -->
<div v-if="loading" class="loading-container">
<el-icon class="is-loading" size="24">
<Loading />
</el-icon>
<span>数据加载中...</span>
</div>
<!-- 空数据提示 -->
<div v-else-if="tableData.length === 0" class="empty-container">
<el-empty description="暂无数据" />
</div>
<!-- 卡片式数据展示 -->
<div v-else class="data-cards">
<div
v-for="(item, index) in tableData"
:key="index"
class="data-card-item"
>
<!-- 顶部:序号和问卷标题 -->
<div class="card-header">
<div class="card-index">#{{ item.dcWjId }}</div>
<div class="card-title">{{ item.dcWjTitle }}</div>
</div>
<!-- 中间:被测评人、部门、提交状态、总分 -->
<div class="card-middle">
<div class="card-row">
<div class="card-label">被测评人:</div>
<div class="card-value">{{ item.dcName }}</div>
</div>
<div class="card-row">
<div class="card-label">部门:</div>
<div class="card-value">{{ item.dcDept }}</div>
</div>
<div class="card-row">
<div class="card-label">提交状态:</div>
<div class="card-value">
<el-tag :type="item.state === '1' ? 'success' : 'info'" size="small">
{{ item.state === '1' ? '已提交' : '未提交' }}
</el-tag>
</div>
</div>
<div class="card-row">
<div class="card-label">总分:</div>
<div class="card-value">{{ item.score || '--' }}</div>
</div>
</div>
<!-- 底部:创建时间、提交时间和操作按钮 -->
<div class="card-bottom">
<div class="time-row">
<div class="time-label">创建时间:</div>
<div class="time-value">{{ formatTime(item.createTime) }}</div>
</div>
<div class="time-row">
<div class="time-label">提交时间:</div>
<div class="time-value">{{ formatTime(item.updateTime) }}</div>
</div>
<div class="action-buttons">
<el-button
size="small"
type="primary"
@click="handleView(item)"
class="action-button"
>
{{ item.state === '1' ? '查看' : '编辑' }}
</el-button>
</div>
</div>
</div>
</div>
<!-- 分页控件 -->
<div class="pagination-container">
<el-pagination
v-model:current-page="pagination.current"
v-model:page-size="pagination.size"
:page-sizes="[5, 10, 20, 50]"
layout="total, sizes, prev, pager, next, jumper"
:total="pagination.total"
@size-change="handleSizeChange"
@current-change="handlePageChange"
/>
</div>
</el-card>
</div>
</template>
<script setup>
// 确保正确导入所有 Vue 函数
import { ref, reactive, onMounted, onUnmounted } from 'vue';
import axios from 'axios';
import {
Document,
User,
OfficeBuilding,
Search,
Refresh,
Loading
} from '@element-plus/icons-vue';
import { ElMessage } from 'element-plus';
import { useRouter } from 'vue-router';
const router = useRouter();
// ...其他变量和函数保持不变...
// 时间格式化函数
const formatTime = (timeString) => {
if (!timeString) return '--';
try {
// 尝试解析时间字符串
const date = new Date(timeString);
// 如果解析失败,返回原始字符串
if (isNaN(date.getTime())) return timeString;
// 格式化为 YYYY-MM-DD HH:mm:ss
return date.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false
}).replace(/\//g, '-');
} catch (e) {
console.error('时间格式化失败:', e);
return timeString;
}
};
// ...其他函数保持不变...
</script>
<style scoped>
/* 移动端适配样式 */
.detail-container {
padding: 12px;
display: flex;
flex-direction: column;
gap: 16px;
}
/* 卡片容器样式 */
.data-cards {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 16px;
}
/* 单个数据卡片样式 */
.data-card-item {
border: 1px solid #ebeef5;
border-radius: 8px;
padding: 16px;
background-color: #fff;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
transition: all 0.3s;
display: flex;
flex-direction: column;
gap: 12px;
}
.data-card-item:hover {
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
transform: translateY(-2px);
}
/* 卡片顶部样式 */
.card-header {
display: flex;
align-items: center;
gap: 10px;
padding-bottom: 12px;
border-bottom: 1px solid #f0f0f0;
}
.card-index {
font-size: 18px;
font-weight: bold;
color: #409eff;
min-width: 40px;
}
.card-title {
font-size: 16px;
font-weight: 600;
color: #1a1a1a;
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
/* 卡片中部样式 */
.card-middle {
display: flex;
flex-direction: column;
gap: 8px;
flex: 1;
}
.card-row {
display: flex;
align-items: center;
gap: 8px;
}
.card-label {
font-size: 14px;
color: #606266;
min-width: 70px;
}
.card-value {
font-size: 14px;
color: #303133;
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* 卡片底部样式 */
.card-bottom {
display: flex;
flex-direction: column;
gap: 8px;
padding-top: 12px;
border-top: 1px dashed #f0f0f0;
}
.time-row {
display: flex;
align-items: center;
gap: 8px;
}
.time-label {
font-size: 13px;
color: #909399;
min-width: 70px;
}
.time-value {
font-size: 13px;
color: #606266;
flex: 1;
}
.action-buttons {
display: flex;
justify-content: flex-end;
margin-top: 8px;
}
.action-button {
width: 100%;
}
/* 加载状态样式 */
.loading-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 40px 0;
gap: 16px;
}
.is-loading {
animation: rotating 2s linear infinite;
}
@keyframes rotating {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
/* 空数据样式 */
.empty-container {
padding: 40px 0;
}
/* 分页样式 */
.pagination-container {
margin-top: 20px;
display: flex;
justify-content: center;
}
/* 响应式设计 */
@media (max-width: 768px) {
.data-cards {
grid-template-columns: 1fr;
}
.card-header {
flex-direction: column;
align-items: flex-start;
gap: 6px;
}
.card-title {
font-size: 15px;
}
.card-label, .time-label {
min-width: 60px;
}
.action-button {
width: 100%;
}
}
@media (max-width: 480px) {
.detail-container {
padding: 8px;
}
.data-card-item {
padding: 12px;
}
.card-title {
font-size: 14px;
}
.card-label, .card-value,
.time-label, .time-value {
font-size: 13px;
}
.pagination-container {
overflow-x: auto;
}
}
</style>
```
### 主要修改说明:
1. **卡片布局设计**:
- 将表格布局改为卡片布局,使用网格布局(`grid`)展示数据
- 每个卡片包含三个部分:顶部、中间和底部
- 添加悬停效果提升用户体验
2. **卡片结构划分**:
```html
<!-- 单个数据卡片 -->
<div class="data-card-item">
<!-- 顶部:序号和问卷标题 -->
<div class="card-header">
<div class="card-index">#{{ item.dcWjId }}</div>
<div class="card-title">{{ item.dcWjTitle }}</div>
</div>
<!-- 中间:被测评人、部门、提交状态、总分 -->
<div class="card-middle">
<!-- 四行信息展示 -->
</div>
<!-- 底部:创建时间、提交时间和操作按钮 -->
<div class="card-bottom">
<!-- 时间信息和操作按钮 -->
</div>
</div>
```
3. **响应式设计优化**:
- 移动端单列显示
- 小屏幕设备上的字体大小调整
- 标签和值的布局优化
4. **时间格式化函数**:
```javascript
const formatTime = (timeString) => {
if (!timeString) return '--';
try {
// 尝试解析时间字符串
const date = new Date(timeString);
// 格式化为 YYYY-MM-DD HH:mm:ss
return date.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false
}).replace(/\//g, '-');
} catch (e) {
return timeString;
}
};
```
5. **加载状态和空状态处理**:
```html
<!-- 加载状态 -->
<div v-if="loading" class="loading-container">
<el-icon class="is-loading" size="24">
<Loading />
</el-icon>
<span>数据加载中...</span>
</div>
<!-- 空数据状态 -->
<div v-else-if="tableData.length === 0" class="empty-container">
<el-empty description="暂无数据" />
</div>
```
### 卡片布局特点:
1. **顶部区域**:
- 序号使用醒目的蓝色和加粗字体
- 问卷标题支持多行显示,最多2行
- 添加底部边框分隔
2. **中间区域**:
- 四行信息展示:被测评人、部门、提交状态和总分
- 标签和值使用弹性布局对齐
- 提交状态使用标签样式展示
3. **底部区域**:
- 创建时间和提交时间使用较小字体
- 时间标签使用灰色字体
- 操作按钮根据状态显示"编辑"或"查看"
4. **响应式设计**:
- 桌面端:多列网格布局
- 平板端:单列布局
- 手机端:优化字体大小和间距
### 实现原理:
1. **网格布局**:
```css
.data-cards {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 16px;
}
```
- 使用CSS Grid创建自适应网格
- `auto-fill`自动填充可用空间
- `minmax(300px, 1fr)`设置最小宽度300px,最大1fr
2. **卡片内部结构**:
```css
.data-card-item {
display: flex;
flex-direction: column;
gap: 12px;
}
```
- 使用Flexbox垂直布局
- `gap`属性统一设置间距
3. **文本截断处理**:
```css
.card-title {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
```
- 支持多行文本截断
- 最多显示2行
4. **时间格式化**:
- 使用`toLocaleString`方法本地化时间显示
- 替换斜杠为短横线
- 添加错误处理防止解析失败
### 注意事项:
1. **性能优化**:
- 对于大量数据,使用分页加载
- 考虑使用虚拟滚动技术
2. **数据加载状态**:
- 显示加载动画提升用户体验
- 空数据状态使用Element Plus的Empty组件
3. **操作按钮**:
- 根据提交状态显示不同的按钮文本
- 已提交状态显示"查看",未提交显示"编辑"
4. **响应式断点**:
- 根据实际设备调整响应式断点
- 使用媒体查询优化不同屏幕尺寸的显示效果
阅读全文
相关推荐







