No More Posting New Topics!

If you have a question or an issue, please start a thread in our Github Discussions Forum.
This forum is closed for new threads/ topics.

Navigation

    Quasar Framework

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search

    How to pause player in component in another instance of the component

    CLI
    2
    6
    413
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • O
      omgwalt last edited by omgwalt

      I’ve added vue-plyr to my little SPA to let it play audio files from a playlist of podcast episodes, and I have everything figured out and working except for one thing.

      The player is in a component that appears once on the page for each instance of the playlist. So with a playlist of 25 episodes, there are 25 instances of the component on the page.

      What I can’t figure out is if one instance is playing an episode, and the user clicks another episode’s player in a separate instance, how to tell the first episode in the first instance to stop playing.

      Vue-plyr wants me to fire this.player.pause within the player component to pause the player, but of course the current “this” refers to the newly playing player instance, not to the old one.

      I’ve declared a property called oldPlay to keep track of the id of the old player instance, but I cannot figure out how to get the old instance to receive the oldPlay property after the new player instance starts playing and apply this.player.pause within the old player instance.

      Here’s what I have so far.

      playlist (parent) vue page:

      <template>
        <q-page class="flex-center">
            <div v-for="item in feed" :key="item.id">
              <h6>{{ item.title }}</h6>
              <p>{{ item.description }}</p>
              <player
                :mp3="item.mp3"
                :id="item.id"
                :oldPlay="oldPlay"
                @play="play(item.id)"
              ></player>
              <hr>
            </div>
        </q-page>
      </template>
      
      <script>
      export default {
        data() {
          return {
            feed: this.$feed,
            oldPlay: 0
          }
        },
        components: {
          'player' : require('components/Player.vue').default
        },
        methods: {
          play(id){
            this.oldPlay = id
          }
        }
      }
      </script>
      

      player (child) component vue page:

      <template>
          <vue-plyr ref="plyr">
            <audio preload="none">
              <source :src="mp3" type="audio/mp3" />
            </audio>
          </vue-plyr>
      </template>
      
      <script>
      export default {
        name: 'Player',
        props: {
          mp3: String,
          id: Number,
          oldPlay: Number
        },
        computed: {
          player() {
            return this.$refs.plyr.player
          }
        },
        data(){
          return{
            play: false
          }
        },
        mounted(){
          this.playIt()
       },
        methods: {
          playIt(){
            this.player.on('play', () => this.$emit('play'))
          }
        }
      }
      </script>
      

      Help!

      1 Reply Last reply Reply Quote 0
      • J
        jraez last edited by

        Use refs attribute, in your parent. You’ll be able to call child methods.

        https://vuejs.org/v2/api/#ref

        O 1 Reply Last reply Reply Quote 0
        • O
          omgwalt @jraez last edited by

          @jraez Okay, I can see the potential value of refs in this case, but how would I apply them in this case? I need to in some way tell the old instance to fire this.player.pause. How could I use refs to accomplish this?

          1 Reply Last reply Reply Quote 0
          • J
            jraez last edited by jraez

            I can’t write the whole code for you but here something to starts with.

             <player
                      :mp3="item.mp3"
                      :ref="`player_${item.id}`"
                      :id="item.id"
                      :oldPlay="oldPlay"
                      @play="play(item.id)"
                    ></player>
            
             play (id){
               if (this.oldPlay) {    
               this.$refs[`player_${id}`].stop()
              }
              this.oldPlay = id
             }
            
            O 1 Reply Last reply Reply Quote 0
            • O
              omgwalt @jraez last edited by

              @jraez Okay, thanks for the start. I’m confused by this note in the docs: “You should avoid accessing $refs from within templates or computed properties.” Isn’t that what we’d be doing here, accessing a ref from within a template?

              1 Reply Last reply Reply Quote 0
              • J
                jraez last edited by

                Nop, you access through a component’s method. This is the basic use-case.

                In a template, it’s like writing :

                <template>
                 <div ref="one">test</div>
                 <div>{{$refs.one.$el.html}}</div>
                </template>
                

                in computed, it’s all that belongs to your component computed() property

                export default { 
                 name: "MyComponent",
                 computed () {
                    test ()  {
                      console.log(this.$refs.one.$el.html)
                    }
                  }
                }
                
                1 Reply Last reply Reply Quote 0
                • First post
                  Last post