50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | Expanding Cards (展开式卡片)

📅 我们继续 50 个小项目挑战!------ Expanding Cards 组件

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

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


✨ 组件目标

  • 一组横向排列的背景卡片
  • 点击卡片后,其展开至主要区域,其他卡片收缩
  • 显示当前卡片的标题,其他隐藏

🧱 技术实现点

  • Vue3 的响应式状态 ref
  • v-for 渲染卡片列表
  • TailwindCSS flex, transition, bg-cover, rounded, bg-[url] 等核心工具类
  • 条件样式绑定 :class

🔧 ExpandingCards.vue 组件实现

html 复制代码
<template>
  <div class="flex min-h-screen justify-center p-20">
    <div
      v-for="item in imagList"
      :key="item.id"
      @click="current = item.id"
      :class="[
        'relative m-2 flex-1/12 cursor-pointer rounded-[4vw] bg-cover bg-center bg-no-repeat font-mono text-2xl text-white transition-all duration-500 ease-in-out',
        item.className,
        current === item.id ? 'flex-2/3' : 'flex-1/12',
      ]">
      <h3
        :class="[
          'absolute bottom-5 left-15 transition-all duration-500 ease-in-out',
          current === item.id ? 'opacity-100' : 'opacity-0',
        ]">
        {{ item.title }}
      </h3>
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const current = ref(1)

const imagList = [
  {
    id: 1,
    className:
      'bg-[url(https://images.unsplash.com/photo-1558979158-65a1eaa08691?auto=format&fit=crop&w=1350&q=80)]',
    title: 'Explore The World',
  },
  {
    id: 2,
    className:
      'bg-[url(https://images.unsplash.com/photo-1572276596237-5db2c3e16c5d?auto=format&fit=crop&w=1350&q=80)]',
    title: 'Wild Forest',
  },
  {
    id: 3,
    className:
      'bg-[url(https://images.unsplash.com/photo-1507525428034-b723cf961d3e?auto=format&fit=crop&w=1353&q=80)]',
    title: 'Sunny Beach',
  },
  {
    id: 4,
    className:
      'bg-[url(https://images.unsplash.com/photo-1551009175-8a68da93d5f9?auto=format&fit=crop&w=1351&q=80)]',
    title: 'City on Winter',
  },
  {
    id: 5,
    className:
      'bg-[url(https://images.unsplash.com/photo-1549880338-65ddcdfd017b?auto=format&fit=crop&w=1350&q=80)]',
    title: 'Mountains - Clouds',
  },
]
</script>

💡 TailwindCSS 样式重点讲解

类名 功能描述
flex-1/12, flex-2/3 自定义比例控制卡片展开宽度
bg-cover bg-center 背景图片尺寸与居中展示
rounded-[4vw] 圆角自定义为视口宽度
transition-all duration-500 平滑过渡效果
opacity-0 / opacity-100 控制标题显隐

🦌 常量定义 + 组件路由

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

js 复制代码
export const projectList = [
    {
        id: 1,
        title: 'Expanding Cards',
        image: 'https://50projects50days.com/img/projects-img/1-expanding-cards.png',
        link: 'ExpandingCards',
    }
]

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

js 复制代码
{
        path: '/ExpandingCards',
        name: 'ExpandingCards',
        component: () => import('@/projects/ExpandingCards.vue')
    }

🚀 小结

这个组件展示了如何用非常少的代码和工具类实现炫酷 UI 效果。我们学会了:

  • 使用 v-for 构建动态组件结构
  • 用 ref 管理当前状态
  • 动态绑定 class 实现动画和交互反馈
  • 熟练使用 TailwindCSS v4 的实用工具类,提升开发效率

📅 明日预告:Progress Steps!实现步骤引导组件。


🧠 每天进步一点点,50 天后惊艳所有人!

相关推荐
栀椩3 分钟前
Electron 内嵌页面跨域问题(CORS/PNA)解决全记录
前端·javascript·electron
SEO_juper12 分钟前
Chrome 扩展一键查看当前页面 SEO 信息:不用切页面,点一下全出来
前端·javascript·chrome
Highcharts.js14 分钟前
CSUN 2026|Highcharts无障碍数据与AI分享
javascript·人工智能·数据分析·highcharts·图表开发
系统集成-鹰翔39 分钟前
ERP推单数据库怎么备份:SQLite WAL模式下只复制db文件为什么可能漏任务
javascript·数据库·经验分享·后端
小大宇2 小时前
Vue知识点-ElementPlus-05 输入框
前端·javascript·vue.js
软件技术NINI2 小时前
基于SpringBoot和Vue的摇滚乐鉴赏网站
vue.js·spring boot·后端·spring·html·毕业设计·毕设
外贸GEO优化2 小时前
外贸独立站的可抓取性:JS 渲染、懒加载与无限滚动到底影响什么
开发语言·javascript·ecmascript
web打印社区2 小时前
Lodop在Edge和双核浏览器-先分清内核
前端·javascript·edge·pdf·ecmascript·html5
系统集成-鹰翔2 小时前
ERP对接升级提示数据库迁移失败:SQLite逐版本事务到底回滚到哪一步
javascript·数据库·经验分享·后端
计算机毕设定制辅导-无忧学长2 小时前
《基于物品协同过滤的闲置书换购微信小程序设计开发》
java·vue.js·spring boot·微信小程序·uniapp·闲置书换购微信小程序·物品协同过滤算法