ibufu / vue2-scrollspy

Scrollspy for Vue2
https://ibufu.github.io/vue2-scrollspy/
MIT License
135 stars 32 forks source link

Force Scrollspy to update with new options #32

Closed jdvivar closed 6 years ago

jdvivar commented 6 years ago

I haven't found a way to force Scrollspy to update with new options. My offset for instance, can change. I have the value saved in a store's state. With this implementation, when the value of the offset changes in the store, it keeps being the original one set when calling Vue.use(Scrollspy, ...) for the first time. What am I missing?

<template>
  <nav class="navigation no-print">
    <ul
      v-scroll-spy-active
      v-scroll-spy-link>
      <li
        v-for="section in sections"
        :key="section.id">
        <a :href="`#${section.id}`">{{ section.heading }}</a>
      </li>
    </ul>
  </nav>

</template>

<script>
// Scrollspy
import Scrollspy, { Easing } from 'vue2-scrollspy'
import Vue from 'vue'
import store from '../store'

Vue.use(Scrollspy, {
  easing: Easing.Cubic.InOut,
  offset: store.state.scrollSpyOffset
})

export default {
  name: 'Navigation',
  props: {
    sections: {
      type: Array,
      default: () => []
    }
  }
}
</script>
jdvivar commented 6 years ago

I think this is a limitation from Vue in regards to how plugins are installed. You can only use Vue.use(...) once.

Here, the official documentation about plugins in Vue: https://vuejs.org/v2/guide/plugins.html

Here, a question in the official phorum from someone with the same issue: https://forum.vuejs.org/t/multiple-vue-use-configurations-for-same-plugin-on-different-pages-of-spa-need-to-reinit-plugin-or-uninstall-plugin-somehow-do-reverse-of-vue-use/37569

@ibufu I might look into a way to allow the plugin to have its options updated manually. I just need your help to know whether there's a way to do it in the actual state of the plugin, and if not, how complex do you think it would be to add that functionality? I'm more than welcome to study your plugin and propose a PR if necessary, just would love some guidance/comments from you first :)

Also, why your plugin is not in the awesome vue list? haha

ibufu commented 6 years ago

Vue.use(plugin, option); This option is a global option that can be override.

v-scroll-spy="{offset: offsetYouSet}"
export default {
  data() {
    return {
       offsetYouSet: 10
    }
  }
}
jdvivar commented 6 years ago

@ibufu I know it can be overridden, but I need to override it many times. Vue.use will only have effect the first time.

For instance, the mobile and desktop versions of the same page can have (and will probably have different offsets).

ibufu commented 6 years ago

@jdvivar Could you change the value of offsetYouSet with many times? Vue.use only effect once in most of Vue plugins.

jdvivar commented 6 years ago

In your example, imagine I add this to the template:

<input v-model="offsetYouSet" type="number">

When user changes the input value I need the offset to change and the value indeed changes. But the the scroll spy will still use the original value of the offset.

Do you understand the problem now? If you don't know anyway to do this with your plugin, just tell me so I can plan into improving your plugin with a function to expose this new functionality. Thanks!

ibufu commented 6 years ago

Sorry, I will solve this issue today.

ibufu commented 6 years ago

@jdvivar Is this demo helpful?

jdvivar commented 6 years ago

@ibufu it works in your demo! Thanks so much for the demo! I used similar code and didn't work for me, but I'll reconsider.