You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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>

优化点说明

  1. 状态简化:移除了每个movie对象中的open和hideImg属性,改用单个activeMovieId管理状态,减少冗余数据。
  2. 性能提升:无需遍历上千条数据修改状态,仅通过判断ID匹配即可控制展开/收起,避免了大量不必要的DOM更新和数组操作。
  3. 逻辑清晰:toggle方法逻辑极简,仅处理当前点击的电影ID,代码可读性更强。

内容的提问来源于stack exchange,提问作者Mateusz Szumilo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 02:30:59