Vue中切换按钮功能异常问题求助
Vue电影列表按钮切换Bug修复
问题1:hideImg状态仅能切换一次
原因
按钮点击事件使用了name.hideImg = !name.hideImg && toggle(name.id)的逻辑与表达式,存在两处问题:
- 当
!name.hideImg为false时,整个表达式结果为false,直接将name.hideImg设为false;后续点击时,!name.hideImg变为true,但toggle方法无返回值(默认返回undefined),导致name.hideImg被赋值为undefined,v-if判断失效。 - 逻辑与会导致
toggle方法仅在!name.hideImg为true时才执行,不符合“点击按钮同时切换图标和视频状态”的需求。
修复
将点击事件拆分为两个独立操作,确保hideImg始终正确切换,同时执行toggle方法:
@click="movie.hideImg = !movie.hideImg; toggle(movie.id)"
问题2:打开全部4个视频后无法再切换显示状态
原因
组件data中未声明全局的open变量,仅在每个movie对象里定义了open,但模板中v-show="name.id == open"引用的是组件实例的this.open。由于未在data中声明,this.open不是响应式变量,修改它不会触发视图更新,多次操作后状态彻底混乱。
修复
在组件data的根级别添加open: null,让其成为响应式变量;同时删除每个movie对象中无用的open属性:
data() { return { open: null, // 添加全局响应式变量 movies: [ // ... 原有电影数据(移除每个对象里的open: null) ] } }
修改后的完整代码
Template部分
<template> <div v-for="(movie, index) in movies" :key="movie.id" class="movieContainer"> <div class="center"> {{ movie.name }} {{ movie.duration }} <button @click="movie.hideImg = !movie.hideImg; toggle(movie.id)" class="watchBtn" > <p v-if="movie.hideImg">►</p> <p v-else>▼</p> </button> </div> <div v-show="movie.id == open"> <video controls="controls" autoplay name="media"> <source :src="require(`@/assets/movie${index + 1}.mp4`)" alt="video" type="video/mp4" width="500px" /> </video> </div> </div> </template>
Script部分
export default { name: "App", methods: { toggle(id) { this.open = this.open === id ? null : id; }, }, data() { return { open: null, movies: [ { name: "Pokemon", duration: "1hr 12min", hideImg: true, id: 1, }, { name: "Digimon", duration: "2hr 37min", hideImg: true, id: 2, }, { name: "Transformers", duration: "1hr 51min", hideImg: true, id: 3, }, { name: "Kiepscy", duration: "1hr 51min", hideImg: true, id: 4, }, ], }; }, };
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; } .movieContainer video { width: 500px; }
内容的提问来源于stack exchange,提问作者Mateusz Szumilo
相关产品推荐
相关产品推荐

