当前位置: 首页 > 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.lryc.cn/news/582174.html

相关文章:

  • 什么是Web3?金融解决方案
  • 康布雷时刻:AI革命中的领导力觉醒与组织重构
  • uniapp下拉刷新+分页组件(z-paging 组件)
  • 2. 你可以说一下 http 版本的发展过程吗
  • 选择排序算法详解(含Python实现)
  • CentOS-7-x86_64解决:使用NAT模式无法ping通www.baidu.com或无法ping 8.8.8.8问题。
  • 阿里arthas(阿尔萨斯)简介
  • 安卓10.0系统修改定制化____recovery-from-boot.p文件的具体作用 在定制项目中的关联
  • v-for的用法及案例
  • 股票筹码分布及其数据获取
  • Swift 解 LeetCode 320:一行单词有多少种缩写可能?用回溯找全解
  • 深入解析TCP:可靠传输的核心机制与实现逻辑(三次握手、四次挥手、流量控制、滑动窗口、拥塞控制、慢启动、延时应答、面向字节流、粘包问题)
  • 沉浸式视频的未来:MV-HEVC与3D-HEVC技术深度解析
  • 【STM32】const 变量存储学习笔记
  • 6,Receiving Messages:@KafkaListener Annotation
  • 【网络】Linux 内核优化实战 - net.ipv4.ip_local_port_range
  • 【方案】前端UI布局的绝技,响应式布局,多端适配
  • 医疗AI底层能力全链条工程方案:从技术突破到临床落地
  • 如何排查服务器中已经存在的后门程序?
  • Java基础--封装+static
  • 软件工程功能点估算基础
  • 软件工程功能点估算法常用术语介绍
  • jmm-内存屏障
  • MMaDA:多模态大型扩散语言模型
  • 边缘计算新底座:基于VPP+DPDK的开放智能网关
  • kafka总结
  • AI + 数据治理的趋势:让治理更智能、更敏捷
  • Web Worker:让前端飞起来的隐形引擎
  • 七牛云Java开发面试题及参考答案(60道面试题汇总)
  • 【C语言】指针与回调机制学习笔记