当前位置: 首页 > news >正文

50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | ContentPlaceholder(背景占位)

📅 我们继续 50 个小项目挑战!—— ContentPlaceholder组件

仓库地址:https://github.com/SunACong/50-vue-projects

项目预览地址:https://50-vue-projects.vercel.app/

在这里插入图片描述


使用 Vue 3 的 Composition API(<script setup>)结合 TailwindCSS 构建一个带有“骨架屏”加载动画的卡片组件。该组件会在数据加载期间显示占位符动画,在数据加载完成后展示真实内容。

🎯 组件目标

  • 创建一个独立、可复用的卡片组件
  • 使用 v-if 控制加载状态切换视图
  • 在数据加载时展示骨架屏动画(Skeleton Loader)
  • 数据加载完成后展示真实内容(标题、摘要、作者信息等)
  • 使用 TailwindCSS 快速构建 UI 样式
  • 模拟异步数据加载过程(使用 setTimeout

⚙️ 技术实现点

技术点描述
Vue 3 <script setup>使用响应式变量管理加载状态
ref 响应式变量控制是否已加载完成
onMounted 生命周期钩子模拟异步请求
setTimeout模拟网络延迟
v-if 条件渲染切换加载动画与真实内容
TailwindCSS 动画类实现骨架屏的脉冲动画效果
TailwindCSS 布局类构建卡片结构、图片裁剪、文字排版

🧱 组件实现

模板结构 <template>

<template><div class="flex h-screen items-center justify-center bg-gray-100"><div class="w-[350px] overflow-hidden rounded-xl bg-white shadow-lg"><!-- 图片头部 --><div v-if="!loaded" class="h-[200px] w-full animate-pulse bg-gray-300" /><img v-else :src="data.headerImg" class="h-[200px] w-full object-cover" /><!-- 内容区域 --><div class="space-y-4 p-6"><!-- 标题 --><div v-if="!loaded" class="h-[20px] w-3/4 animate-pulse rounded bg-gray-300" /><h3 v-else class="text-xl font-bold text-gray-800">{{ data.title }}</h3><!-- 摘要 --><div v-if="!loaded" class="space-y-2"><div class="h-[10px] w-full animate-pulse rounded bg-gray-300"></div><div class="h-[10px] w-5/6 animate-pulse rounded bg-gray-300"></div><div class="h-[10px] w-2/3 animate-pulse rounded bg-gray-300"></div></div><p v-else class="text-gray-600">{{ data.excerpt }}</p><!-- 作者 --><div class="flex items-center"><divv-if="!loaded"class="h-10 w-10 animate-pulse rounded-full bg-gray-300"></div><imgv-else:src="data.profileImg"class="h-10 w-10 rounded-full object-cover" /><div class="ml-3"><divv-if="!loaded"class="h-[10px] w-[100px] animate-pulse rounded bg-gray-300"></div><template v-else><strong class="text-gray-800">{{ data.name }}</strong><small class="text-gray-500">{{ data.date }}</small></template></div></div></div></div></div>
</template>

脚本逻辑 <script setup>

<script setup>
import { ref, onMounted } from 'vue'const loaded = ref(false)const data = {headerImg:'https://images.unsplash.com/photo-1496181133206-80ce9b88a853?auto=format&fit=crop&w=2102&q=80',title: 'Lorem ipsum dolor sit amet',excerpt: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolore perferendis.',profileImg: 'https://randomuser.me/api/portraits/men/45.jpg',name: 'John Doe',date: 'Oct 08, 2020',
}onMounted(() => {setTimeout(() => {loaded.value = true}, 2500)
})
</script>

🔍 重点效果实现

✅ 加载动画(骨架屏)实现

我们通过 v-if="!loaded" 控制加载动画的显示,并使用 TailwindCSS 提供的 animate-pulse 类实现脉冲动画效果:

<div class="h-[20px] w-3/4 animate-pulse rounded bg-gray-300"></div>

这是典型的骨架屏样式:灰色背景 + 动画闪烁,模拟文本或图像即将出现的效果。

💡 真实内容展示

loaded.value 变为 true 后,所有 v-else 分支被激活,显示真实的图片、标题、摘要和用户信息。

📦 数据模拟加载过程

我们使用 setTimeout 模拟了一个 2.5 秒的网络请求延迟:

onMounted(() => {setTimeout(() => {loaded.value = true}, 2500)
})

这使得组件在挂载后不会立即展示内容,而是等待一定时间后才显示,模拟了真实场景中的异步加载行为。


🎨 TailwindCSS 样式重点讲解

类名作用
h-screen, items-center, justify-center全屏高度 + 居中布局
bg-gray-100设置浅灰色背景
w-[350px], h-[200px]固定宽度和高度
rounded-xl圆角卡片
shadow-lg添加阴影增强视觉层次
object-cover图片自适应容器
p-6内边距设置
space-y-4子元素垂直间距
animate-pulse骨架屏动画
bg-gray-300占位块颜色
rounded-full头像圆形裁剪

这些类组合起来实现了现代感十足的卡片样式和流畅的过渡动画。


📁 常量定义 + 组件路由

constants/index.js 添加组件预览常量:

{id: 24,title: 'Content Placeholder',image: 'https://50projects50days.com/img/projects-img/24-content-placeholder.png',link: 'ContentPlaceholder',},

router/index.js 中添加路由选项:

{path: '/ContentPlaceholder',name: 'ContentPlaceholder',component: () => import('@/projects/ContentPlaceholder.vue'),},

🏁 总结

适合用于新闻资讯、社交动态、产品列表等需要异步加载数据的场景。

你可以进一步扩展此组件的功能包括:

  • ✅ 支持主题切换(深色/浅色模式)
  • ✅ 封装为通用 <AppCardLoader /> 组件,支持传入任意数据对象
  • ✅ 支持多个卡片并列展示(卡片列表)
  • ✅ 添加淡入动画(fade-in
  • ✅ 支持响应式布局(适配移动端)

👉 下一篇,我们将完成StickyNavbar组件,一个具有现代风格的网站主页组件。🚀

感谢阅读,欢迎点赞、收藏和分享 😊

http://www.dtcms.com/a/269033.html

相关文章:

  • 电动汽车的传导发射仿真
  • navicate如何设置数据库引擎
  • RabbitMQ在SpringBoot中的使用详解
  • 2025光学成像与机器视觉国际会议 (OIMV 2025)
  • 用Python制作华夫图:从零开始
  • ShortGPT: Layers in Large Language Models are More Redundant Than You Expect
  • delphi,c++程序 阻止Win11 用户更改系统时间
  • 电子防抖(EIS)技术概述
  • Springboot 如何加密数据库连接相关配置信息
  • 特伦斯T1节拍器,突出综合优势与用户体验
  • AI建站工具对决:Wegic、腾讯云、Hocoos、Typedream深度测评,谁是国内用户的首选?
  • MySQL Galera Cluster企业级部署
  • 【Python】VSCode:解决模块导入与调试
  • 【音视频】HLS简介与服务器搭建
  • 【LLIE专题】通过预训练模型先验提升暗光增强模型复原效果
  • 安卓10.0系统修改定制化____如何修改固件 去除开机向导 实现开机直接进入桌面
  • C++笔记之开关控制的仿真与实际数据处理优雅设计
  • 基于物联网的城市低洼地段水深报警系统设计
  • 【人工智能学习路线(一)】以SCI为目标学习笔记——Python 编程基础入门
  • 面试总结46-50天
  • Python爬虫图片验证码和滑块验证码识别总结
  • 前端技术博客汇总文档
  • 思考5-10分钟,输出高质量的学术科研报告,谷歌的deepsearch模型太惊艳了!
  • 【最新版】Spring Boot 项目打包部署到服务器
  • 【配置+图解Android各种版本配置】
  • V8 主要版本与对应 ECMAScript 支持
  • 2025 API 开发管理工具 Apipost 与 Apifox 全维度对比
  • CentOS-7-x86_64解决:使用NAT模式无法ping通www.baidu.com或无法ping 8.8.8.8问题。
  • 防火墙防御DDoS攻击能力分析
  • AI 智能体记忆系统关键技术