mercs600 / vue2-perfect-scrollbar

Vue.js wrapper for perfect scrollbar
https://mercs600.github.io/vue2-perfect-scrollbar/
MIT License
275 stars 43 forks source link

Scrollbar don't show up on hover, but works and show up when scrolling? #6

Closed ivan-stojanov closed 5 years ago

ivan-stojanov commented 5 years ago

I have pretty much the same issue which is described here, but the described solutions there are for plane jQuery and for Angular. Here is the problem: the div where the perfect scrollbar is applied, is hidden by default and then when I'm opening it, initially the scrollbar is hidden (it's not visible when I hover over the div) and once I start scrolling, it is appearing and everything works fine from that moment. Based on the ideas in the link above, I tried to implement something as:

In the main.js I'm using the global registration:

import PerfectScrollbar from 'vue2-perfect-scrollbar'
import 'vue2-perfect-scrollbar/dist/vue2-perfect-scrollbar.css'

Vue.use(PerfectScrollbar, { options: { wheelPropagation: true }})

And then in my component I'm having the usage in the HTML like (the ID for my <div> is created dynamically and this piece of HTML is in a hidden <div> when the page loads):

... some HTML content ...
<ul>
   <perfect-scrollbar :id="'some-dynamic-id-' + thisIsVariableID">
      <li v-for="(vale, index) in list" :key="index">
         ... some HTML content ...
      </li>
   </perfect-scrollbar >
</ul>
... some HTML content ...

I tried adding the following code in all of the hooks created(), beforeMount() and mounted() but it was not working (also tried the same without the setInterval() function):

let selfComponent = this;
setTimeout(() => {
   let ps = document.getElementById('some-dynamic-id-' + selfComponent.thisIsVariableID);
   ps.perfectScrollbar('update');
}, 0);

So if there is any idea how to make this working in my VueJS project please let me know.

mercs600 commented 5 years ago

@ivan0071 the clue is update perfect scrollbar instance after your HTML is updated (not only data)

let's see example: https://codesandbox.io/s/korz7o1zlv

I have array "someList" which is empty on init.

  data() {
    return {
      someList: []
    };
  },

In mounted cycle I push some additional data for my array, but after some time (setTimeout on 2000ms).

mounted() {
    setTimeout(() => {
      this.someList = ["one", "two", "three", "one", "two", "three"];

      this.$nextTick(() => {
        this.$refs.scroll.update();
      });
    }, 2000);
  }

After you update your data you have to wait to vuejs update your HTML - so I used $nextTick (https://vuejs.org/v2/guide/reactivity.html)

I created reference on my perfect-scrollbar element to use update method inside of perfect scrollbar component.

  <perfect-scrollbar ref="scroll">

you have to think in this way ;-) I hope it will be helpful for you

ivan-stojanov commented 5 years ago

Hello @mercs600,

Thank you very much for the help. Using the vue refs with the combination of this.$nextTick solved the issue for me.

Here are more details in case someone else got this problem:

... some HTML content ...
<ul>
   <perfect-scrollbar :ref="'some-dynamic-id-' + thisIsVariableID">
      <li v-for="(vale, index) in list" :key="index">
         ... some HTML content ...
      </li>
   </perfect-scrollbar >
</ul>
... some HTML content ...

then this <div> was shown on an user click on a button, where I added:

v-on:click="showPerfectScrollbar()"

and then in the methods() I now have:

showPerfectScrollbar() {
      let self = this;
      self.$nextTick(() => {
         self.$refs['some-dynamic-id-' + self.tabId].update();
      });
},

And now all works as I expected! Cheers!

mercs600 commented 5 years ago

Nice ;-)

BorisAng commented 4 years ago

@mercs600 What shall we do in the case when the dynamic data is inside a computed property just like the one bellow:

  computed: {
    convertedBids () {
      let resultArray = []
      for (let i = 0; i < this.bids.length; i++) {
        let currentBid = this.bids[i]
        let resultObject = {
          btype: currentBid.btype,
          nj_date: this.$moment(currentBid.nj_date).format('MMM D, YYYY'),
          ref: currentBid.nj_numb,
          title: `Bid No. ${currentBid.nj_numb}`,
          value: currentBid.nj_name,
          wf_ref: currentBid.nj_ref
          // to: 'app.bid.summary'
        }
        resultArray.push(resultObject)
      }
      return resultArray
    }
  }

Template:

<template>
  <b-list-group class="border rounded mb-4">
    <perfect-scrollbar
      class="scroll-area"
      ref="scroll"
      :options="settings">
        <bid-or-job
          v-for="(bid, index) in convertedBids"
          :key="bid.wf_ref"
          :item="bid"
          :class="{'last-row': index === convertedBids.length - 1}"/>
    </perfect-scrollbar>
  </b-list-group>
</template>

I have tried adding the following, which has no positive effect

  mounted () {
    setTimeout(() => {
      this.$nextTick(() => {
        this.$refs.scroll.update()
      })
    }, 5000)
  }

Neither does this:

  watch: {

   convertedBids (newVal) {
      console.log('newVal', newVal)
      setTimeout(() => {
        this.$nextTick(() => {
          this.$refs.scroll.update()
        })
      }, 5000)
    }
  }

I've also tried updating the scrollbar inside the computed property after the loop has executed but in this case the bar is discovered only after the property has returned, hence updating the bar before it has returned does not work.

BorisAng commented 4 years ago

@mercs600 The solution was to wrap the b-list-group with perfect-scrollbar rather than the other way around

<template>
  <perfect-scrollbar
    class="scroll-area mb-4 border rounded"
    ref="scroll"
    :options="settings">
      <b-list-group>
        <b-list-group-item
          v-if="noResults"
          class="
            border-top-0
            border-right-0
            border-left-0
            border-bottom
            px-4
            py-1
            rounded-0
            bg-primary
            text-white">
              <font-awesome-icon
                icon="exclamation-circle"/>
                No Bids Found !
        </b-list-group-item>
        <bid-or-job
          v-else
          v-for="(bid, index) in convertedBids"
          :key="bid.wf_ref"
          :item="bid"
          :class="{'last-row': index === convertedBids.length - 1}"/>
      </b-list-group>
  </perfect-scrollbar>
</template>
whimsicaldreamer commented 1 year ago

Is update available for vue3-perfect-scrollbar?