通过商店的Nuxtjs ScrollSpy

时间:2020-07-29 13:10:43

标签: javascript vue.js vuex nuxt.js

Codesandbox:https://codesandbox.io/s/romantic-pond-ehixi?file=/pages/index.vue

嗨,让我在问题出现之前先解释一下设计,以便我们所有人都持相同观点?

我目前是Vue的新手,正在Vuex商店从事Nuxtjs项目。 在我的layout/default.vue中,我有一个HeaderFooter组件,以及它们之间的<Nuxt />HeaderFooter的顶部和底部均为固定/粘滞状态。 主要内容将是可滚动的,并且其中包含卡片。

⚙️问题:

Header组件将具有导航,当正确的卡片在视口中时(至少100像素偏移),导航将突出显示。 在Footer组件中,有一些按钮可根据用户正在查看的卡,将用户导航到上一张或下一张卡(包括100px偏移)。

我正在使用vue2-scrollspy,但是它不起作用(请参阅codeandbox)。我也不确定这是否是正确的模块。

⚠️UPDATE 01

当用户滚动页面时,Scroll Spy现在正在工作,我添加了一个观察器以更新存储值。剩下的问题是根据用户查看的内容将其滚动到上一张或下一张卡片。在vue2-scrollspy文档上,显示以下内容。

$scrollTo(index: int) is provided on scope Vue instance to invoke a scroll to the given section index.

但是,致电$scrollTo(0)this.$scrollTo(0)给我一个错误:

this.$scrollTo is not a function

Codesandbox已更新为最新更改?

1 个答案:

答案 0 :(得分:0)

好的,这就是我解决问题的方式?

/pages/index.vue上,我在每张卡上添加了 ID ,并且在每次滚动间谍更改count的值时,都有观察者检查。如果count发生更改,我将更新store.global [currentView,previousView,nextView]上的值。

? /pages/index.vue

<template>
  <main class="main" v-scroll-spy="{ data: 'count', offset: 250 }">
    <div
      :key="item"
      v-for="(item, index) in sections"
      :id="`view-${index}`"
      class="main-child card"
      :class="[`bg-${index}`]"
    >
      <h1>{{ item }}</h1>
      <p>{{ `${index} ${item} ${count}` }}</p>
    </div>
  </main>
</template>

<script>
export default {
  data() {
    return {
      count: 0
    };
  },
  computed: {
    sections() {
      return this.$store.state.sections;
    }
  },
  watch: {
    count(newValue) {
      this.$store.dispatch("updateCurrentView", newValue);
      this.$store.dispatch(
        "updatePreviousView",
        newValue === 0 ? 0 : newValue - 1
      );
      this.$store.dispatch(
        "updateNextView",
        newValue === this.sections.length - 1
          ? this.sections.length - 1
          : newValue + 1
      );
    }
  }
};
</script>

? /store/index.js

export const state = () => ({
  global: {
    currentView: 0,
    previousView: 0,
    nextView: 1
  },
  sections: ["first", "second", "third", "fourth", "fifth", "sixth"]
});

export const mutations = {
  UPDATE_CURRENT_VIEW(state, value) {
    state.global.currentView = value;
  },
  UPDATE_PREVIOUS_VIEW(state, value) {
    state.global.previousView = value;
  },
  UPDATE_NEXT_VIEW(state, value) {
    state.global.nextView = value;
  }
};

export const actions = {
  updateCurrentView({ commit }, value) {
    commit("UPDATE_CURRENT_VIEW", value);
  },
  updatePreviousView({ commit }, value) {
    commit("UPDATE_PREVIOUS_VIEW", value);
  },
  updateNextView({ commit }, value) {
    commit("UPDATE_NEXT_VIEW", value);
  }
};

然后在按钮updown所在的组件上,我可以调用全局状态并添加操作以基于全局值滚动到上一个或下一个元素:

? /components/WithUpDownButtons.vue

export default {
  computed: {
    global() {
      return this.$store.state.global
    }
    ...
  },
  methods: {
    scrollTopPrevious() {
      // scroll to previous element into view
      // this.$scrollTo(this.previousView) < not working
      document
        .getElementById(`view-${this.global.previousView}`)
        .scrollIntoView(true);
    },
    scrollTopNext() {
      // scroll to next element into view
      // this.$scrollTo(this.nextView) < not working
      document
        .getElementById(`view-${this.global.nextView}`)
        .scrollIntoView(true);
    }
  }
};

如果需要添加滚动动画,可以使用以下内容更新scrollIntoView(true)

? /components/WithUpDownButtons.vue

...
  methods: {
    scrollTopPrevious() {
      // scroll to previous element into view
      document
        .getElementById(`view-${this.global.previousView}`)
        .scrollIntoView({
          top: 0,
          behavior: 'smooth'
        });
    },
    scrollTopNext() {
      // scroll to next element into view
      document
        .getElementById(`view-${this.global.nextView}`)
        .scrollIntoView({
          top: 0,
          behavior: 'smooth'
        });
    }
  }
...
相关问题