我们继续 50 个小项目挑战!—— MovieApp
组件
仓库地址:https://github.com/SunACong/50-vue-projects
项目预览地址:https://50-vue-projects.vercel.app/
使用 Vue 3 的 Composition API 和 语法结合 TailwindCSS 构建一个电影信息展示组件。该组件将从 TMDb 获取热门电影数据,并支持通过关键词进行搜索,点击卡片还能查看影片简介。
技术点 | 描述 |
---|---|
Vue 3 Composition API ( ) |
使用响应式变量管理组件状态 |
ref 响应式变量 |
控制搜索词和电影数据 |
async/await 异步请求 |
调用 TMDb API 获取电影数据 |
v-for 渲染电影列表 |
动态生成多个电影卡片 |
:class 动态绑定类名 |
根据评分设置不同颜色样式 |
TailwindCSS 动画与布局 | 构建美观的交互界面 |
<template>
<div class="relative h-16 bg-gray-900">
<input
type="text"
class="absolute top-3 right-3 h-10 rounded-2xl bg-gray-600 p-2"
placeholder="Search"
v-model="searchTerm" />
div>
<div class="flex flex-wrap items-center justify-center gap-6 p-4">
<div
v-for="item in movies"
:key="item.id"
class="group relative flex-1/6 overflow-hidden bg-white transition-all duration-300 hover:shadow-lg">
<img :src="IMG_PATH + item.poster_path" alt="" class="h-4/6 w-full object-cover" />
<div class="p-2">
<div class="text-lg font-bold">{{ item.title }}div>
<div class="text-sm text-gray-500">{{ item.release_date }}div>
<div class="text-sm text-gray-500">{{ item.vote_average }}div>
div>
<div
class="absolute right-0 bottom-0 left-0 translate-y-full transform overflow-y-auto bg-white p-4 transition-transform duration-300 ease-out group-hover:translate-y-0">
<div class="mb-4 font-mono text-2xl">Overviewdiv>
<div class="font-mono text-gray-700">
{{ item.overview || 'No overview available' }}
div>
div>
div>
div>
template>
<script setup>
import { ref, onMounted } from 'vue'
const movies = ref([])
const searchTerm = ref('')
const IMG_PATH = 'https://image.tmdb.org/t/p/w1280'
const API_URL =
'https://api.themoviedb.org/3/discover/movie?sort_by=popularity.desc&api_key=3fd2be6f0c70a2a598f084ddfb75487c&page=1'
const SEARCH_API =
'https://api.themoviedb.org/3/search/movie?api_key=3fd2be6f0c70a2a598f084ddfb75487c&query='
const getMovies = async (searchTerm = '') => {
const url = searchTerm ? `${SEARCH_API}${searchTerm}` : API_URL
try {
const response = await fetch(url)
if (!response.ok) throw new Error('Network response was not ok')
const data = await response.json()
movies.value = data.results
} catch (error) {
console.error('Fetch error:', error)
movies.value = []
}
}
onMounted(() => getMovies())
</script>
我们通过调用 TMDb 提供的 API 加载热门电影数据:
const API_URL = 'https://api.themoviedb.org/3/discover/movie?sort_by=popularity.desc&api_key=...'
并在 onMounted()
生命周期中加载初始数据:
onMounted(() => getMovies())
通过监听输入框的 v-model
并触发搜索函数:
<input v-model="searchTerm" @input="getMovies(searchTerm)" />
每部电影的图片地址为相对路径,需要拼接基础 URL:
<img :src="IMG_PATH + item.poster_path" />
使用 Tailwind 的 group-hover
类实现在鼠标悬停时滑出电影简介:
<div class="absolute ... group-hover:translate-y-0">
类名 | 作用 |
---|---|
h-16 , h-4/6 |
设置高度为固定值或比例 |
bg-gray-900 , bg-gray-600 |
设置深色背景 |
rounded-2xl |
圆角较大 |
p-2 , p-4 |
内边距控制 |
flex-wrap , justify-center |
布局控制 |
transition-all duration-300 |
过渡动画持续时间为 0.3 秒 |
hover:shadow-lg |
鼠标悬停时添加大阴影 |
overflow-hidden |
防止内容溢出容器 |
absolute , translate-y-full |
初始状态下隐藏简介 |
group-hover:translate-y-0 |
鼠标进入后显示简介 |
这些 Tailwind 工具类帮助我们快速构建了一个视觉丰富、交互性强的电影卡片展示界面。
constants/index.js
添加组件预览常量:
{
id: 17,
title: 'Movie App',
image: 'https://50projects50days.com/img/projects-img/17-movie-app.png',
link: 'MovieApp',
},
router/index.js
中添加路由选项:
{
path: '/MovieApp',
name: 'MovieApp',
component: () => import('@/projects/MovieApp.vue'),
},
这个电影卡片展示组件不仅是一个优秀的学习项目,也非常适合用于实际应用中,如影视推荐网站、个人观影记录页面等。它涵盖了 Vue 3 的异步请求、响应式数据绑定、条件渲染以及 TailwindCSS 的灵活样式组合能力。
你可以进一步扩展的功能包括:
感谢阅读,欢迎点赞、收藏和分享
下一篇,我们将完成BackgroundSlider
组件,一个非常具有现代风格的手动轮播组件!