v-for内的传值
-
给v-for内的对象绑定事件,只对某个对象触发事件,是需要传值的,通过v-for内的属性,触发事件的同时会将对应的属性传递给方法来接收
这里通过
@click='selectedSong(index)'向selectedSong方法传当前被点击的li的index值 -
方法内通过
this.selectSong = index将被点击的对象的index值赋值给唯一的属性selectSong,通过这个属性的值来判断到底是点击了哪个,来操作数组对应index的对象或属性 -
这里就是通过传出的index通过
:class='{active:index == selectSong}'将selectSong的值赋值给index,来为被点击的对象添加 active 类 -
v-for的对象内嵌套事件,也是需要通过传值来判断事件的目标,传入不同的属性,处理方式就不一样,这里传入的song,相当于给事件提供了this指向,来给this下的collect属性通过isCollect方法来赋值
另一个方法是传入
index:<div class="btn"> <img @click.stop='isCollect(index)' v-if='song.collect' src="img/collected.svg" alt=""> <img @click.stop='isCollect(index)' v-else src="img/collect.svg" alt=""> <img src="img/play.svg" alt=""> </div>isCollect(index) { this.musicList[index].collect = !this.musicList[index].collect; }这个方法是点击后,通过传出的
index值找到对应数组内的对象,再对对象内的属性赋值 -
v-for内的对象嵌套v-if获取this指向也是通过传值来实现的,这里传入了song,为了让if显示else隐藏后,还可以触发事件,需要两个元素都绑定上点击事件,这个方法适用于不需要频繁切换的内容另一个方法就是用 v-show :
<div @click.stop='isCollect(index)'> <img v-show='song.collect' src="img/collected.svg" alt=""> <img v-show='!song.collect' src="img/collect.svg" alt=""> </div>给父元素添加点击事件,然后内部的元素均添加
v-show,不同的是,在其中一个的属性前方加!取非,以此来实现toggle
<li class="song" v-for='(song,index) in musicList' :key='index'
:class='{active:index == selectSong}' @click="selectedSong(index)">
<div>
<p class="index">{{index+1}}</p>
<img class="song-cover" :src="song.cover" alt="">
<div class="title">
<h5>{{song.title}}</h5>
<h6>{{song.singer}}</h6>
</div>
</div>
<div class="btn">
<img @click.stop='isCollect(song)' v-if='song.collect' src="img/collected.svg"
alt="">
<img @click.stop='isCollect(song)' v-else src="img/collect.svg" alt="">
<img src="img/play.svg" alt="">
</div>
</li>
data:{
selectSong: -1,//通过设置index初始值为-1,来让默认选中的元素为空
playerstatus: false,
playingInfo: {
title: '暂无播放',
singer: ' ',//带有标签或为html内容时使用v-html插值
cover: 'img/cover/blank.jpg',
src: '',
...
},
musicList:[
{
...
cover: 'img/cover/xxx.jpg',
src: 'music/xxx.mp3',
collect: false,
...
},
]
},
methords:{
selectedSong(index) {
this.selectSong = index;
},
isCollect(song) {
song.collect = !song.collect;//通过取反,来实现toggle
}
},
watch: {
selectSong: function (newV) {
this.playingInfo = this.musicList[newV];
this.playerstatus = true;
},
}
- 通过侦听
selectSong的index值的变化做出反应,将index对应的数组中的对象全部属性覆盖给播放器对象属性
列表的循环
数组的长度为0-14 index 的15 length 个对象,所以需要 -1 让 length = index
<div class="btn">
<img @click='prevBtn' src="img/next.svg" alt="">
<div @click='stopMusic'>
<img v-show='playerstatus' src='img/puased.svg' alt="">
<img v-show='!playerstatus' src='img/play.svg' alt="">
</div>
<img @click='nextBtn' src="img/next.svg" alt="">
</div>
data:{
playerstatus: false,
},
methords:{
stopMusic() {
this.playingInfo = this.playerInitial;//把播放器初始化的属性值赋值给播放器
this.playerstatus = false;
},
prevBtn() {
if (this.selectSong > 0) {//判断当前选中的对象index是否等于0
this.selectSong--;//大于0,就表示没有选中第一个,可以一直-1
} else {
this.selectSong = this.musicList.length - 1;//等于0的时候让值等于数组最后一个对象的index
}
},
nextBtn() {
if (this.selectSong < this.musicList.length - 1) {//判断当前选中的对象index是否等于数组最后一个对象的index
this.selectSong++;//小于的话,表示没有选中最后一个,可以一直+1
} else {
this.selectSong = 0;//等于数组长度时,再次点击,让index=0,选中第一个
}
}
}
对歌词添加注释
对歌词统一添加一段注释,if用来判断lrc是否为初始的空值,控制的话为false则什么都不做,播放器的lrc属性值被更改后,有了值则变为true,执行if内的处理,添加注释,dom内插值时插入计算方法
用
watch给this.playingInfo.lrc覆盖的话会导致多次添加的问题,用computed,少写一个添加注释后的属性,更方便
computeds:{
lrcNote() {
if (this.playingInfo.lrc) {
return `<span>请手动滚动歌词</span><br>${this.playingInfo.lrc}`
}
},
}