50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | GoodCheapFast(Good - Cheap - Fast三选二开关)

发布于:2025-07-19 ⋅ 阅读:(10) ⋅ 点赞:(0)

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

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

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

在这里插入图片描述


使用 Vue 3 的 Composition API 和 TailwindCSS 创建一个经典的交互式组件 —— “Good - Cheap - Fast” 三选一开关控制。这个组件模拟了项目开发中常见的权衡原则:你只能同时拥有其中两个选项。通过点击任意一个开关,用户可以动态切换状态,并自动关闭其他其中一个已开启的选项。


🎯 组件目标

  • 实现“三选二”的互斥选择逻辑
  • 提供美观的自定义开关按钮样式(基于 TailwindCSS)
  • 使用 Vue 3 Composition API 管理响应式状态与交互逻辑
  • 支持清晰的 UI 反馈(颜色、文本提示)

⚙️ 技术实现点

技术点 描述
Vue 3 <script setup> 使用 ref 管理三个布尔状态(good、cheap、fast)
自定义函数 toggleFeature 控制开关行为并确保最多只开启两个选项
TailwindCSS 样式 构建现代感十足的开关组件和布局
动态类绑定 根据开关状态动态调整颜色和位置

🧱 组件实现

模板结构 <template>

<template>
    <div class="flex min-h-screen items-center justify-center bg-gray-100">
        <div class="w-96 rounded-lg bg-white p-8 shadow-lg">
            <h1 class="mb-6 text-center text-2xl font-bold">Good - Cheap - Fast 三选一</h1>
            <div class="space-y-4">
                <!-- 高质量 -->
                <div class="flex items-center justify-between">
                    <span class="text-gray-700">高质量 (Good)</span>
                    <label class="flex cursor-pointer items-center">
                        <input type="checkbox" class="hidden" :checked="good" @change="toggleFeature('good')" />
                        <div :class="['h-6 w-12 rounded-full bg-gray-300 p-1 transition-all', good ? 'bg-green-500' : '']">
                            <div :class="['h-4 w-4 rounded-full bg-white transition-all', good ? 'translate-x-6' : '']"></div>
                        </div>
                        <span :class="['ml-2 text-sm font-medium', good ? 'text-green-500' : 'text-gray-500']">{{ good ? 'ON' : 'OFF' }}</span>
                    </label>
                </div>

                <!-- 低成本 -->
                <div class="flex items-center justify-between">
                    <span class="text-gray-700">低成本 (Cheap)</span>
                    <label class="flex cursor-pointer items-center">
                        <input type="checkbox" class="hidden" :checked="cheap" @change="toggleFeature('cheap')" />
                        <div :class="['h-6 w-12 rounded-full bg-gray-300 p-1 transition-all', cheap ? 'bg-green-500' : '']">
                            <div :class="['h-4 w-4 rounded-full bg-white transition-all', cheap ? 'translate-x-6' : '']"></div>
                        </div>
                        <span :class="['ml-2 text-sm font-medium', cheap ? 'text-green-500' : 'text-gray-500']">{{ cheap ? 'ON' : 'OFF' }}</span>
                    </label>
                </div>

                <!-- 快速交付 -->
                <div class="flex items-center justify-between">
                    <span class="text-gray-700">快速交付 (Fast)</span>
                    <label class="flex cursor-pointer items-center">
                        <input type="checkbox" class="hidden" :checked="fast" @change="toggleFeature('fast')" />
                        <div :class="['h-6 w-12 rounded-full bg-gray-300 p-1 transition-all', fast ? 'bg-green-500' : '']">
                            <div :class="['h-4 w-4 rounded-full bg-white transition-all', fast ? 'translate-x-6' : '']"></div>
                        </div>
                        <span :class="['ml-2 text-sm font-medium', fast ? 'text-green-500' : 'text-gray-500']">{{ fast ? 'ON' : 'OFF' }}</span>
                    </label>
                </div>
            </div>
        </div>
    </div>
</template>

该模板构建了一个简洁而直观的界面,每个功能项都包含一个标签和一个自定义样式的开关控件,支持用户交互。


脚本逻辑 <script setup>

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

// 初始化三个开关状态
const good = ref(false)
const cheap = ref(false)
const fast = ref(false)

// 计算当前已开启的功能数量
const getActiveCount = () => {
    let count = 0
    if (good.value) count++
    if (cheap.value) count++
    if (fast.value) count++
    return count
}

// 实现切换功能的方法
const toggleFeature = (feature) => {
    switch (feature) {
        case 'good':
            // 如果当前已经有两个开启,且要开启 good,则需要关闭一个
            if (!good.value && getActiveCount() >= 2) {
                // 关闭第一个开启的其他功能
                if (cheap.value) cheap.value = false
                else if (fast.value) fast.value = false
            }
            good.value = !good.value
            break
        case 'cheap':
            if (!cheap.value && getActiveCount() >= 2) {
                if (good.value) good.value = false
                else if (fast.value) fast.value = false
            }
            cheap.value = !cheap.value
            break
        case 'fast':
            if (!fast.value && getActiveCount() >= 2) {
                if (good.value) good.value = false
                else if (cheap.value) cheap.value = false
            }
            fast.value = !fast.value
            break
    }
}
</script>

脚本部分主要处理开关的逻辑判断和状态管理,确保始终只有最多两个功能处于开启状态。


🎨 TailwindCSS 样式重点讲解

类名 作用
flex, min-h-screen, items-center, justify-center 创建全屏垂直居中的布局
bg-gray-100 设置背景颜色为浅灰色,增加视觉层次感
rounded-lg, bg-white, p-8, shadow-lg 定义卡片样式的边框圆角、内边距及阴影效果
text-2xl, font-bold, text-center 标题样式设置
space-y-4 控制每组开关之间的垂直间距
cursor-pointer 当鼠标悬停在开关上时显示为手形光标
transition-all 添加平滑的动画过渡效果
translate-x-6 控制开关内部圆形滑块的位置偏移,表示 ON 状态
bg-green-500, text-green-500 表示开启状态下的颜色反馈

这些 TailwindCSS 类共同构建出一个现代风格的交互组件。


🔍 关键功能解析

✅ 三选二逻辑实现

核心在于 toggleFeature 函数,它根据当前激活的开关数量进行判断:

  • 如果用户尝试打开第三个选项,将自动关闭最早开启的一个。
  • 这种互斥机制保证了“Good - Cheap - Fast”模型的核心原则始终成立。

💡 用户体验优化

  • 开关状态以颜色变化(绿色/灰色)和文字提示(ON/OFF)即时反馈给用户。
  • 滑动动画增强交互的真实感和趣味性。

📁 常量定义 + 组件路由

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

{
        id: 32,
        title: 'Good Cheap Fast',
        image: 'https://50projects50days.com/img/projects-img/32-good-cheap-fast.png',
        link: 'GoodCheapFast',
    },

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

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

🏁 总结

使用 Vue 3 Composition API 和 TailwindCSS 实现了一个经典的“Good - Cheap - Fast”三选二开关组件。通过合理的状态管理和优雅的样式设计,我们不仅实现了功能上的需求,还提供了良好的用户体验。

你可以扩展以下功能:

  • ✅ 添加复位按钮:一键关闭所有开关。
  • ✅ 记录历史状态:让用户查看之前的选择组合。
  • ✅ 加入图标或图片:提升视觉表达力。

👉 下一篇,我们将完成AnimatedCountdown组件,非常有意思的倒计时动画组件。🚀

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


网站公告

今日签到

点亮在社区的每一天
去签到