好看的卡片
- 简介卡片
@\components\myAside.vue
<-template->
<-div v-if="asideshow.user" class="card-content1 shadow-box background-opacity"->
<-el-avatar style="margin-top: 20px" class="user-avatar" :size="120" :src="userInfo.userPic"-><-/el-avatar->
<-div class="web-name"->{{ userInfo.username }}<-/div->
<-div class="web-info"->
<-div class="blog-info-box"->
<-span->昵称<-/span->
<-span class="blog-info-num"->{{ userInfo.nickname }}<-/span->
<-/div->
<-div class="blog-info-box"->
<-span->名称<-/span->
<-span class="blog-info-num"->{{ userInfo.username }}<-/span->
<-/div->
<-div class="blog-info-box"->
<-span->身份<-/span->
<-span class="blog-info-num"->{{ userInfo.identity }}<-/span->
<-/div->
<-/div->
<-a class="collection-btn"->
<-i class="el-icon-star-off" style="margin-right: 2px"-><-/i->{{ userInfo.email }}
<-/a->
<-/div->
<-/template->
style
<-style scoped->
.card-content1 {
background: linear-gradient(-45deg, #e8d8b9, #eccec5, #a3e9eb, #bdbdf0, #eec1ea);
background-size: 400% 400%;
animation: gradientBG 10s ease infinite;
display: flex;
flex-direction: column;
align-items: center;
border-radius: 10px;
position: relative;
overflow: hidden;
}
.card-content1 :not(:first-child) {
z-index: 10;
}
.web-name {
font-size: 30px;
font-weight: bold;
margin: 20px 0;
}
.web-info {
width: 80%;
display: flex;
flex-direction: row;
justify-content: space-around;
}
.blog-info-box {
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
}
.blog-info-num {
margin-top: 12px;
}
.collection-btn {
position: relative;
margin-top: 12px;
background: var(--lightGreen);
cursor: pointer;
width: 65%;
height: 35px;
border-radius: 1rem;
text-align: center;
line-height: 35px;
color: var(--white);
overflow: hidden;
z-index: 1;
margin-bottom: 25px;
}
.collection-btn::before {
background: var(--gradualRed);
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
content: "";
transform: scaleX(0);
transform-origin: 0;
transition: transform 0.5s ease-out;
transition-timing-function: cubic-bezier(0.45, 1.64, 0.47, 0.66);
border-radius: 1rem;
z-index: -1;
}
.collection-btn:hover::before {
transform: scaleX(1);
}
.shadow-box {
box-shadow: 0 1px 20px -6px var(--borderColor);
transition: all 0.3s ease;
}
.shadow-box:hover {
box-shadow: 0 5px 10px 5px var(--borderHoverColor);
}
<-/style->
- 博客卡片
@\components\common\ResourceCardList.vue
<-template->
<-div class="card-container" v-if="resourcePathList.length"->
<-div v-for="(resourcePath, index) in resourcePathList"
:key="index"
class="card-item shadow-box wow"
@click="clickResourcePath(resourcePath)"->
<-div class="card-image"->
<-el-image class="my-el-image"
v-once
lazy
:src="resourcePath.cover"
fit="cover"->
<-template #error->
<-div class="image-slot myCenter" style="background-color: var(--lightGreen)"->
<-div class="error-text"->
<-div->遇事不决,可问春风<-/div->
<-/div->
<-/div->
<-/template->
<-/el-image->
<-/div->
<-div class="card-body"->
<-div class="card-title"->
<-span v-if="resourcePath.recommendStatus"->
🔥
<-/span->
{{ resourcePath.title }}
<-/div->
<-div class="card-desc"->
{{ resourcePath.introduction }}
<-/div->
<-div class="card-time"->
<-svg viewBox="0 0 1024 1024" width="14" height="14" style="vertical-align: -2px;"->
<-path d="M512 512m-512 0a512 512 0 1 0 1024 0 512 512 0 1 0-1024 0Z" fill="#409EFF"-><-/path->
<-path
d="M654.222222 256c-17.066667 0-28.444444 11.377778-28.444444 28.444444v56.888889c0 17.066667 11.377778 28.444444 28.444444 28.444445s28.444444-11.377778 28.444445-28.444445v-56.888889c0-17.066667-11.377778-28.444444-28.444445-28.444444zM369.777778 256c-17.066667 0-28.444444 11.377778-28.444445 28.444444v56.888889c0 17.066667 11.377778 28.444444 28.444445 28.444445s28.444444-11.377778 28.444444-28.444445v-56.888889c0-17.066667-11.377778-28.444444-28.444444-28.444444z"
fill="#FFFFFF"-><-/path->
<-path
d="M725.333333 312.888889H711.111111v28.444444c0 31.288889-25.6 56.888889-56.888889 56.888889s-56.888889-25.6-56.888889-56.888889v-28.444444h-170.666666v28.444444c0 31.288889-25.6 56.888889-56.888889 56.888889s-56.888889-25.6-56.888889-56.888889v-28.444444h-14.222222c-22.755556 0-42.666667 19.911111-42.666667 42.666667v341.333333c0 22.755556 19.911111 42.666667 42.666667 42.666667h426.666666c22.755556 0 42.666667-19.911111 42.666667-42.666667v-341.333333c0-22.755556-19.911111-42.666667-42.666667-42.666667zM426.666667 654.222222h-56.888889c-17.066667 0-28.444444-11.377778-28.444445-28.444444s11.377778-28.444444 28.444445-28.444445h56.888889c17.066667 0 28.444444 11.377778 28.444444 28.444445s-11.377778 28.444444-28.444444 28.444444z m227.555555 0h-56.888889c-17.066667 0-28.444444-11.377778-28.444444-28.444444s11.377778-28.444444 28.444444-28.444445h56.888889c17.066667 0 28.444444 11.377778 28.444445 28.444445s-11.377778 28.444444-28.444445 28.444444z m0-113.777778h-56.888889c-17.066667 0-28.444444-11.377778-28.444444-28.444444s11.377778-28.444444 28.444444-28.444444h56.888889c17.066667 0 28.444444 11.377778 28.444445 28.444444s-11.377778 28.444444-28.444445 28.444444z"
fill="#FFFFFF"-><-/path->
<-/svg->
发布于 {{ getDateDiff(resourcePath.createTime) }}
<-/div->
<-/div->
<-/div->
<-/div->
<-/template->
<-script setup->
import { defineProps, defineEmits } from 'vue';
const props = defineProps({
resourcePathList: {
type: Array,
required: true
}
});
const emit = defineEmits(['clickResourcePath']);
function clickResourcePath(resourcePath) {
emit("clickResourcePath", resourcePath.id);
}
function getDateDiff(date) {
const now = new Date();
const past = new Date(date);
const diff = now - past;
const seconds = Math.floor(diff / 1000);
const minutes = Math.floor(seconds / 60);
const hours = Math.floor(minutes / 60);
const days = Math.floor(hours / 24);
const months = Math.floor(days / 30);
const years = Math.floor(days / 365);
if (years -> 0) {
return `${years}年前`;
} else if (months -> 0) {
return `${months}个月前`;
} else if (days -> 0) {
return `${days}天前`;
} else if (hours -> 0) {
return `${hours}小时前`;
} else if (minutes -> 0) {
return `${minutes}分钟前`;
} else {
return `刚刚`;
}
}
<-/script->
<-style scoped->
.card-container {
display: flex;
flex-wrap: wrap;
}
.card-item {
position: relative;
border-radius: 10px;
background: rgba(255, 255, 255, .88);
overflow: hidden;
margin: 10px;
height: 300px;
flex-shrink: 0;
width: calc(100% / 3 - 20px);
cursor: pointer;
animation: zoomIn 0.8s ease-in-out;
}
.card-image {
width: 100%;
height: 180px;
}
.card-image ->->-> .el-image__inner {
transition: all 1s;
}
.card-image ->->-> .el-image__inner:hover {
transform: scale(1.2);
}
.card-body {
padding: 10px 20px;
}
.card-title {
font-size: 18px;
font-weight: 600;
margin-bottom: 10px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
transition: all .2s ease-in-out;
}
.card-title:hover {
color: var(--lightGreen);
}
.card-desc {
font-size: 14px;
line-height: 1.5;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
letter-spacing: 1px;
}
.card-time {
position: absolute;
bottom: 10px;
font-size: 12px;
color: var(--greyFont);
}
@media screen and (max-width: 700px) {
.card-item {
width: calc(100% / 2 - 20px);
}
}
@media screen and (max-width: 500px) {
.card-item {
width: calc(100% - 20px);
}
}
<-/style->
@\stores\patients.js
import { defineStore } from 'pinia'
import { ref } from 'vue'
import { DPatientsService } from '@/api/bind.js' // 假设你的服务文件路径是 @/services/apiService
const usePatientsInfoStore = defineStore('patients', () =-> {
const infos = ref([])
// 获取用户信息并更新 store
const fetchInfos = async () =-> {
infos.value = []
try {
const response = await DPatientsService()
console.log('API Response:', response) // 调试输出
if (response.code === 0) { // 确保响应成功
infos.value = response.data
console.log('Fetched Infos:', infos.value) // 调试输出
}
else {
console.error('Error fetching patients info:', response.message)
}
} catch (error) {
console.log('Its OK')
}
}
const setInfo = (newInfos) =-> {
infos.value = newInfos
}
const removeInfo = () =-> {
infos.value = []
}
const clearUserData = () =-> {
infos.value = []
}
return { infos, setInfo, removeInfo, fetchInfos, clearUserData }
}, { persist: true })
export default usePatientsInfoStore
@\components\user.vue
<-template->
<-div v-if="userInfo.identity === 'patient'"->
<-ResourceCardList :resourcePathList="resourcePathList" @clickResourcePath="handleResourceClick" /->
<-/div->
<-/template->
<-script setup->
import ResourceCardList from '@/components/common/ResourceCardList.vue';
const resourcePathList = computed(() =-> {
return filesInfo.value.map((info, index) =-> ({
cover: info.url || 'https://aircraft-1111.oss-cn-beijing.aliyuncs.com/mr_train_1001_middle_slice.jpg',
title: info.fileName,
introduction: '一个 nii 图像',
recommendStatus: true,
createTime: '2024-08-15T00:00:00Z',
url: '/demo',
id: info.id
}))
})
async function handleResourceClick(id) {
console.log('Clicked image id:', id);
imageStore.setImgId(id); // 设置图片ID
await imageStore.fetchImages(id); // 等待获取图片完成
router.push('/demo'); // 获取图片后跳转到/demo路由
}
<-/script->
- 列表卡片
@\components\common\userCard.vue
<-template->
<-div class="card-content shadow-box-mini" @click="handleClick"->
<-div->
<-el-avatar :size="avatarSize" :src="avatarSrc"-><-/el-avatar->
<-/div->
<-div class="card-right"->
<-div class="card-title"->{{ title }}<-/div->
<-div class="card-desc"->{{ description }}<-/div->
<-/div->
<-/div->
<-/template->
<-script setup->
import { defineProps, defineEmits } from 'vue';
const props = defineProps({
avatarSize: {
type: Number,
default: 100
},
avatarSrc: {
type: String,
required: true
},
title: {
type: String,
default: '时光相册'
},
description: {
type: String,
default: '📸记录美好瞬间'
},
clickValue: {
type: Number,
default: 2
}
});
const emit = defineEmits();
function handleClick() {
emit('card-click', props.clickValue);
}
<-/script->
<-style scoped->
.card-content {
display: flex;
padding: 25px;
margin: 25px 0;
border-radius: 20px;
width: 100%;
cursor: pointer;
transition: all 0.3s;
background: var(--background);
}
.card-content:hover {
/* Add hover effects if needed */
}
.card-right {
margin-left: 20px;
}
.card-title {
font-size: 1.6rem;
letter-spacing: 0.2rem;
line-height: 3.5rem;
font-weight: 700;
}
.card-desc {
font-size: 1.1rem;
letter-spacing: 0.2rem;
color: #777777;
}
<-/style->
@\components\cardList.vue
<-template->
<-div class="card-list"->
<-CardComponent
v-for="(card, index) in cards"
:key="index"
:avatarSrc="card.avatarSrc"
:title="card.title"
:description="card.description"
@card-click="handleCardClick(card.id)"
/->
<-/div->
<-/template->
<-script setup->
import { defineProps, defineEmits } from 'vue';
import CardComponent from '@/components/common/userCard.vue'; // 确保路径正确
const props = defineProps({
cards: {
type: Array,
required: true
}
});
const emit = defineEmits();
function handleCardClick(id) {
emit('card-click', id);
}
<-/script->
<-style scoped->
.card-list {
display: flex;
flex-direction: column;
width: 100%;
}
<-/style->
@\components\user.vue
<-template->
<-CardList
v-if="userInfo.identity === 'doctor'"
:cards="cardData"
@card-click="handleCardClick"
/->
<-/template->
<-script setup->
import CardList from '@/components/CardList.vue';
const cardData = computed(() =-> {
return patientsInfos.value.map((info, index) =-> ({
id: info.id,
avatarSrc: info.userPic || IU, // 这里假设所有卡片使用相同的图片
title: `${info.username} (${info.nickname})`,
description: `📸Comment : ${info.comment}`
}))
})
function handleCardClick(id) {
console.log('Card clicked with ID:', id);
findPatientInfo(id)
dialogVisible.value = true; // 显示弹窗
console.log("dialogVisible : " + dialogVisible.value)
getFilesName();
}
<-/script->