一、this.$nextTick(() => {})
<audio ref="audio" :src="currentSong.url"></audio>
// 此处省略几截代码
watch: {
currentSong (song) {
console.log(song)
this.$nextTick(() => {
this.$refs.audio.play()
})
}
},
如果没有$nextTick回调函数,上述代码会引发 Uncaught (in promise) DOMException 报错。具体原因就是在watch监听到currentSong的变化时,<audio>标签的src属性未挂载完毕。直接执行play()方法,则报错。
原理:$nextTick 是在下次 DOM 更新循环结束之后执行延迟回调。
二、computed计算属性根据vuex,state动态变化
原始代码:(固定class,不方便切换)
<div class="icon i-center">
<i class="icon-play" @click="togglePlaying"></i>
</div>
修改后的代码:
<div class="icon i-center">
<i :class="playIcon"
@click="togglePlaying"></i>
// 此处省略一大截代码
computed: {
playIcon () {
return this.playing ? 'icon-pause' : 'icon-playing'
}
}
</div>
个人发言: 要充分发挥各个属性的长处,解决问题的方法可以有很多。但是最适的方法只有一个,举一反三是学习的过程,最终目的是找到解决问题的根本途径。
三、H5 audio控件dom未渲染完毕(vue快速切歌)触发dom异常
作为一个有节操的程序员,我们是不容许这种报错出现的。
个人思路: setTimeout()固定延迟,非常笨拙。
大佬思路: 当控件监听到当前歌曲已播放时,才允许我们切换下一首歌。
解决方案:audio绑定@canplay事件,在事件中增加标志位。
<audio ref="audio"
:src="currentSong.url"
@canplay="ready" // 仅当歌曲开始播放才触发
@error="error" // 网络异常或歌曲不存在,歌曲加载失败
></audio>
// 省略几截代码
data () {
return {
songReady: false // 标志位
}
},
//省略几截代码
next () {
// 当歌曲还在加载阶段,标志位false拦截操作,当true时才执行
if (!this.songReady) {
return
}
let index = this.currentIndex + 1
if (this.currentIndex === this.playlist.length - 1) {
index = 0
}
this.setCurrentIndex(index)
if (!this.playing) {
this.togglePlaying()
}
// 执行完切换歌曲后,标志位重新false
this.songReady = false
},
ready () {
// 当歌曲加载完毕就会,执行@canplay事件,即绑定的ready函数
this.songReady = true
},
error () {
// 为了不影响用户的体验
this.songReady = true
},