Vue电影收藏列表:如何实现单条电影对象的LocalStorage增删?
你的代码存在几个核心问题导致收藏功能失效:
- 未区分原电影列表和收藏列表,把TMDB返回的热门电影数组和收藏电影混在一起存储
- 点击按钮时未传递当前操作的电影对象,方法不知道要处理哪部电影
storeMovie方法中使用的this.movie是空字符串,从未赋值为目标电影对象removeMovie方法直接删除localStorage里的movie键,但实际收藏数据存储逻辑混乱,未针对特定电影删除- 监听
movies数组的watch会把整个热门电影列表覆盖到localStorage,完全不符合收藏需求
修正方案
1. 分离数据结构
在data中新增favorites数组专门存储收藏的电影,和原movies数组彻底分开:
data () { return { movies: [], favorites: [], // 独立存储收藏电影 errored: false, loading: true } }
2. 修改按钮点击逻辑
给按钮传递当前循环的movie对象,同时根据收藏状态动态切换按钮显示:
<div class="card" v-for="movie in movies" :key="movie.id"> {{ movie.title }} {{ movie.release_date }} <button type="button" @click="storeMovie(movie)"> {{ isFavorite(movie) ? '已收藏' : 'Aggiungi' }} </button> <button type="button" @click="removeMovie(movie)" v-if="isFavorite(movie)"> Rimuovi </button> </div>
3. 实现核心操作方法
isFavorite:判断电影是否已在收藏列表中(通过唯一id校验)storeMovie:添加电影到收藏列表,避免重复添加removeMovie:从收藏列表移除指定电影
methods: { isFavorite(movie) { return this.favorites.some(item => item.id === movie.id) }, storeMovie(movie) { if (!this.isFavorite(movie)) { this.favorites.push(movie) } }, removeMovie(movie) { this.favorites = this.favorites.filter(item => item.id !== movie.id) } }
4. 初始化加载收藏数据
在mounted中加载localStorage里的收藏列表,不要覆盖原电影数组:
mounted () { axios .get('https://api.themoviedb.org/3/movie/popular?api_key=###&language=it-IT&page=1&include_adult=false®ion=IT') .then(response => { this.movies = response.data.results }) .catch(error => { console.log(error) this.errored = true }) .finally(() => this.loading = false) // 加载本地存储的收藏数据 const savedFavorites = localStorage.getItem('favorites') if (savedFavorites) { this.favorites = JSON.parse(savedFavorites) } }
5. 自动同步收藏数据到LocalStorage
给favorites数组添加watch监听,自动同步到本地存储:
watch: { favorites: { handler(newFavorites) { localStorage.setItem('favorites', JSON.stringify(newFavorites)) }, deep: true // 监听数组内部对象变化 } }
完整修改后的代码
<template> <div> <div class="card" v-for="movie in movies" :key="movie.id"> {{ movie.title }} {{ movie.release_date }} <button type="button" @click="storeMovie(movie)"> {{ isFavorite(movie) ? '已收藏' : 'Aggiungi' }} </button> <button type="button" @click="removeMovie(movie)" v-if="isFavorite(movie)"> Rimuovi </button> </div> </div> </template> <script> import axios from 'axios' export default { name: 'HomeComp', data () { return { movies: [], favorites: [], errored: false, loading: true } }, mounted () { axios .get('https://api.themoviedb.org/3/movie/popular?api_key=###&language=it-IT&page=1&include_adult=false®ion=IT') .then(response => { this.movies = response.data.results }) .catch(error => { console.log(error) this.errored = true }) .finally(() => this.loading = false) const savedFavorites = localStorage.getItem('favorites') if (savedFavorites) { this.favorites = JSON.parse(savedFavorites) } }, watch: { favorites: { handler(newFavorites) { localStorage.setItem('favorites', JSON.stringify(newFavorites)) }, deep: true } }, methods: { isFavorite(movie) { return this.favorites.some(item => item.id === movie.id) }, storeMovie(movie) { if (!this.isFavorite(movie)) { this.favorites.push(movie) } }, removeMovie(movie) { this.favorites = this.favorites.filter(item => item.id !== movie.id) } } } </script> <style scoped lang="scss"> .card { margin: 1rem 0; padding: 1rem; border: 1px solid #eee; border-radius: 4px; } button { margin-right: 0.5rem; padding: 0.3rem 0.8rem; cursor: pointer; } </style>
关键说明
- 用
favorites数组单独存储收藏电影,和原movies数组完全隔离,避免数据混乱 - 通过电影唯一
id判断收藏状态,确保操作的准确性 - 按钮显示状态动态切换,避免重复添加操作
- 初始化时加载本地收藏数据,刷新页面后收藏不会丢失
- watch监听自动同步收藏数据到LocalStorage,简化方法逻辑
内容的提问来源于stack exchange,提问作者Selene_jpg
相关产品推荐
相关产品推荐

