在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問答/HTML/ vue-router跳轉(zhuǎn)頁面后,子組件音樂播放器的當(dāng)前播放時間會不停在兩個值之前

vue-router跳轉(zhuǎn)頁面后,子組件音樂播放器的當(dāng)前播放時間會不停在兩個值之前跳動?

點(diǎn)擊查看demo github地址

問題描述:
在【音樂播放頁】選中一首歌曲,歌曲能正常播放;
當(dāng)切換到【音樂詳情頁】之后,頁面上的當(dāng)前播放時間會不停的在兩個值中間跳動?
定時器timer已經(jīng)在路由切換的時候關(guān)了,但是還會不停的執(zhí)行timer這個方法


圖片描述

clipboard.png

切換路由后,當(dāng)前播放的音樂播放器組件,時間一直在跳動?

musicBar.vue

<template>
   <div>
     <div style="border: 1px solid #ddd;padding: 10px;margin-top: 50px;">
       <div>
         <p>選中的歌曲列表</p>
         <ul>
           <li v-for="(item,index) in musicList" @click="playListMusic()" :class="{red:currentIndex==index}">{{item.name}}</li>
         </ul>
       </div>
       <button @click="turnMusic"><span>{{isPlayingMsg}}</span></button>
       <button @click="next()">下一首</button>
       <button @click="updateTime()">跳轉(zhuǎn)到上一次位置</button>
       <audio :src=currentMusic.src autoplay  @error="errorFun()" @ended="next()" id="musicId"></audio>
      當(dāng)前播放音樂是:{{currentMusic.name}}
      <!--當(dāng)前播放進(jìn)度:{{musicProgress}}-->
      當(dāng)前播放的時間:{{currentTime}}s
     </div>
   </div>
</template>

<script>
  import $ from "jquery"
  import {mapState,mapMutations,mapActions,mapGetters} from "vuex"
export default {
  name: 'app',
  data () {
    return {
      timer:""
    }
  },
  computed: {
    ...mapGetters(["currentMusic","musicList","musicProgress","currentTime","currentIndex","isPlaying","isPlayingMsg"])
  },
  methods: {
    addMusic: function (item) {
      this.playMusic();
      this.$store.commit("addMusic",item);
    },
    playMusic: function () {
      var audioPlay = document.getElementById("musicId");
      var _this = this;
      var palam={
        musicProgress:"",
        currentTime:""
      }
      var musicProgress;
      _this.timer=setInterval(function () {
          console.log(8);
        palam.musicProgress = audioPlay.currentTime / audioPlay.duration * 100 + "%";
        palam.currentTime = audioPlay.currentTime;
        _this.$store.commit("playMusic",palam);
      }, 500)
      if(audioPlay.currentTime){
        audioPlay.play();
      }
    },
    turnMusic:function () {
      var audioPlay = document.getElementById("musicId");
      this.$store.commit("turnMusic");
      if (this.isPlaying) {
        audioPlay.play();
      }
      else {
        audioPlay.pause();
      }
    },
    errorFun: function () {
      //判斷是否是第一次默認(rèn)加載
      if (this.musicList.length > 0) {
        console.log("歌曲出錯了");
      }
    },
    //播放下一曲
    next: function () {
        this.$store.commit("next");
    },
    //更新進(jìn)度條
    updateTime(){
        console.log("開始更新進(jìn)度條");
      //清除之前的定時器
      clearInterval(this.timer);  //跳轉(zhuǎn)到musicDetail后調(diào)用這個方法,為什么不起作用?
//      var audioPlay = document.getElementById("musicId");
//      audioPlay.currentTime=this.$store.getters.currentTime;  //每次路由跳轉(zhuǎn)后音樂都會重頭開始播放,所以這里我重置音樂開始時間等于上次記錄時間;
      this.playMusic();  //如果不加這句,跳轉(zhuǎn)路由后,音樂就停了;加了之后播放時間會不停跳動
    }
  },
  created:function(){
  }
}
</script>
<style>
  .red{
    color: red;
  }
</style>

musicDeatil.vue

<template>
   <div>
     <h3>我是音樂詳情頁</h3>
     <musicBar ref="musicBar"></musicBar>
   </div>
</template>

<script>
  import $ from "jquery"
  import {mapState,mapMutations,mapActions,mapGetters} from "vuex"
  import musicBar from "./musicBar.vue"
export default {
  name: 'app',
  data () {
    return {
      musicListAll:[
        {
            name:"歌曲一",
            src:"/src/assets/a.mp3",
            id:1
        },
        {
          name:"歌曲二",
          src:"/src/assets/b.mp3",
          id:2
        },
        {
          name:"歌曲三",
          src:"/src/assets/c.mp3",
          id:3
        },
        {
          name:"一首鏈接出錯的歌曲",
          src:"/src/assets/d.mp34",
          id:4
        }
      ]
    }
  },
  computed:{
  },
  methods:{
  },
  components:{
    musicBar
  },
  created:function(){
  },
  //在進(jìn)入路由前
  beforeRouteEnter:function(to,from,next){
    next(function(vm){     //參數(shù)vm代表vue這個實(shí)例
       vm.$refs.musicBar.updateTime();
    });
    //父級觸發(fā)子組件的事件
  },
  //路由離開
  beforeRouteLeave:(to,from,next)=>{
      next();
  }
}
</script>

<style>
</style>

playMusic.vue

<template>
   <div>
     <h3>歌曲列表</h3>
     <ul>
       <li  v-for="item in musicListAll"><a href="javascript:" @click="addMusic(item)">{{item.name}}</a></li>
     </ul>
     <musicBar ref="musicBar"></musicBar>
   </div>
</template>

<script>
  import $ from "jquery"
  import {mapState,mapMutations,mapActions,mapGetters} from "vuex"
  import musicBar from "./musicBar.vue"
export default {
  name: 'app',
  data () {
    return {
      musicListAll:[
        {
            name:"歌曲一",
            src:"/src/assets/a.mp3",
            id:1
        },
        {
          name:"歌曲二",
          src:"/src/assets/b.mp3",
          id:2
        },
        {
          name:"歌曲三",
          src:"/src/assets/c.mp3",
          id:3
        },
        {
          name:"一首鏈接出錯的歌曲",
          src:"/src/assets/d.mp34",
          id:4
        }
      ]
    }
  },
  computed:{
  },
  methods:{
    addMusic:function(item){
        //父組件要觸發(fā)子組件的值,并傳遞參數(shù);
      this.$refs.musicBar.addMusic(item);
    }
  },
  components:{
    musicBar
  },
  created:function(){
  },
  route:{
    data:function(transition){
      console.log(transition);
      console.log(101);
    }
  }
}
</script>

<style>
</style>
回答
編輯回答
尕筱澄

不同頁面調(diào)用同一個組件,但是會生成兩套組件(musicBar)參數(shù),所以會產(chǎn)生兩個定時器timer;
所以在切換router的時候,會有兩個timer不停迭代,應(yīng)該把timer定時器放在vuex中,保持唯一性;

在playMusic.vue 和 musicDetail.vue中添加router的進(jìn)入方法beforRouteEnter;當(dāng)進(jìn)入到這兩個頁面后,先關(guān)閉store中的定時器timer,再打開一個新的定時器,這樣就不會重復(fù);

//  //在進(jìn)入路由前
  beforeRouteEnter:function(to,from,next){
    next(function(vm){     //參數(shù)vm代表vue這個實(shí)例
       vm.$refs.musicBar.updateTime();
    });
  }

在musicBar.vue 中的添加的方法;

  //更新進(jìn)度條
    updateTime(){      
      //清除之前的定時器
      this.$store.commit("clearTime");
      var audioPlay = document.getElementById("musicId");
       audioPlay.pause();
      audioPlay.currentTime=this.$store.getters.currentTime;  //跳轉(zhuǎn)到上次記錄的時間
      if(this.isPlaying){
        this.playMusic();
      }
    }

app.js中使用 keep-alive保持在打開已經(jīng)打開過的頁面時不會重新載入

      <keep-alive>
        <router-view></router-view>
      </keep-alive>
      

router/index.js 中

  setTimer:function(state,timer){
     state.timer=timer;
   },
   clearTime:function(state){
     console.log("在store中清除timer");
     clearInterval(state.timer);
   }
2017年5月23日 05:02