如何在Vue中重置切换项至默认状态(优化多条目切换)
优化方案:单一状态管理实现单选展开
核心思路
不再给每个电影条目维护open和hideImg状态,而是通过一个全局的activeMovieId记录当前展开的电影ID,实现单选展开/收起的逻辑,彻底解决大量数据下的性能问题。
修改后的完整代码
<template> <div v-for="(movie, index) in movies" :key="movie.id" class="movieContainer"> <div class="center"> <h3>{{ movie.name }}</h3> <p class="duration">{{ movie.duration }}</p> <button @click="toggle(movie.id)" class="watchBtn"> <p v-if="activeMovieId !== movie.id">►</p> <p v-else>▼</p> </button> </div> <div v-if="activeMovieId === movie.id"> <video controls="controls" autoplay name="media"> <source :src="require(`@/assets/movie${index + 1}.mp4`)" alt="video" type="video/mp4" width="500px" autoplay /> </video> </div> </div> </template> <script> export default { name: "App", data() { return { activeMovieId: null, // 记录当前展开的电影ID movies: [ { name: "Windy Highway", duration: "15 seconds", id: 1, movieStart: "0:00", movieMid: "0.08", movieEnd: "0:15", }, { name: "Sunny Station", duration: "32 seconds", id: 2, movieStart: "0:00", movieMid: "0.16", movieEnd: "0:32", }, { name: "Abstract Material", duration: "9 seconds", id: 3, movieStart: "0:00", movieMid: "0.05", movieEnd: "0:09", }, { name: "Pumpkin Drilling", duration: "17 seconds", id: 4, movieStart: "0:00", movieMid: "0.09", movieEnd: "0:17", }, ], }; }, methods: { toggle(id) { // 如果点击的是当前展开的,就关闭;否则切换到当前条目 this.activeMovieId = this.activeMovieId === id ? null : id; // 保留原有的日志输出 const currentMovie = this.movies.find(movie => movie.id === id); console.log( currentMovie.movieStart, "-", currentMovie.movieMid, "-", currentMovie.movieEnd ); }, }, }; </script> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin: 60px auto 0; } .watchBtn { background-color: red; border-radius: 10px; margin-left: 10px; height: 20px; display: flex; align-items: center; } .watchBtn:hover { background-color: rgb(255, 191, 107); cursor: pointer; } .movieContainer { margin: 5px auto; display: flex; flex-direction: column; } .center { margin: 0 auto; display: flex; align-items: center; } .duration { margin: 0 5px 0 10px; } .movieContainer video { width: 500px; } </style>
优化点说明
- 状态简化:移除了每个movie对象中的
open和hideImg属性,改用单个activeMovieId管理状态,减少冗余数据。 - 性能提升:无需遍历上千条数据修改状态,仅通过判断ID匹配即可控制展开/收起,避免了大量不必要的DOM更新和数组操作。
- 逻辑清晰:toggle方法逻辑极简,仅处理当前点击的电影ID,代码可读性更强。
内容的提问来源于stack exchange,提问作者Mateusz Szumilo
相关产品推荐
相关产品推荐

