5.7 $nextTick数据渲染完毕回调 computed计算属性动态绑class 解决audio快速切换Uncaught (in promise) DOMException异常

一、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>

注: 其实也可以使用methods充当计算属性的角色,因为MVVM是双向绑定的。故model view的变化会导致dom数值的更新。

个人发言: 要充分发挥各个属性的长处,解决问题的方法可以有很多。但是最适的方法只有一个,举一反三是学习的过程,最终目的是找到解决问题的根本途径

三、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
    },

猜你喜欢

转载自blog.csdn.net/qq_40196738/article/details/89917089