【问题标题】:Watch window.scrollY changes in Vuejs在 Vuejs 中观察 window.scrollY 的变化
【发布时间】:2019-08-18 20:41:55
【问题描述】:

我有一个非常简单的应用程序,它有 2 个组件:App.vue 和另一个组件 Home.vue,我在其中保存了应用程序的其余结构:一个粘性标题和一些带有要滚动到的锚点的部分。

我想为粘性标题应用一个类,以在页面滚动时最小化徽标。所以我想我会留意window.scrollY 的任何变化。因此,如果scrollY 大于 0,则应用一些最小化徽标的类。

我试图在我的组件中监听滚动事件,但这并没有走得太远。在这里的这个讨论中,提供了一个非常好的解决方案,但是我不知道在哪里放置滚动事件。 https://github.com/vuejs/Discussion/issues/324

所以,我认为最合适的解决方案是创建一个数据属性,为其分配window.scrollY 图形,然后观察其值的变化。不幸的是,观察者永远不会被触发。所以现在我被困住了。代码是:

data () {
return {
  ...
  windowTop: window.top.scrollY
 }
}
...
watch: {
 windowTop: {
  immediate: true,
  handler (newVal, oldVal) {
    console.log(newVal, oldVal);
  },
 }
}

关于我可能做错了什么的任何想法?

【问题讨论】:

    标签: javascript vue.js vuejs2


    【解决方案1】:

    window 属性不能像那样被动地使用。相反,您必须听取windowscroll 事件并做出相应响应:

    mounted() {
      window.addEventListener("scroll", this.onScroll)
    },
    beforeDestroy() {
      window.removeEventListener("scroll", this.onScroll)
    },
    methods: {
      onScroll(e) {
        this.windowTop = window.top.scrollY /* or: e.target.documentElement.scrollTop */
      }
    }
    

    【讨论】:

      【解决方案2】:

      您可以使用mounted() 方法将您的事件侦听器添加到窗口对象,如下所示:

      var p = new Vue({
         el: "#app",
         data(){
            return {
                windowTop: 0
            };
         },
         mounted()
         {
             var that = this;
             window.addEventListener("scroll", function(){
                 that.windowTop = window.scrollY;
             });
         },
         template: "<div style='height: 250vh'><div style='position: fixed; right: 0; top: 0'>{{windowTop}}</div></div>"
      });
      <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
      <div id="app"></div>

      【讨论】:

        【解决方案3】:

        2020 年更新:

        使用@scroll.passive 观看组件中任何元素的滚动:

        例子:

        模板

        <div class="room_message-stream" @scroll.passive="handleScroll">
              <ul class="room_message-stream__list">
                <li class="room_message-stream__list-item">...</li>
              </ul>
        </div>
        

        方法:

        handleScroll (e) {
          var scrollPos = e.target.scrollTop
        }
        

        【讨论】:

        • scroll 事件不能是 preventDefaulted,所以 passive 标志在这里没有帮助。该标志通常用于 improve scrolling performance 用于昂贵的 touchstart/touchmove 事件处理程序。
        【解决方案4】:

        对我来说,以上都不起作用。

        我必须将true 作为添加/删除滚动监听器中的第三个参数传递:

        mounted() {
          window.addEventListener("scroll", this.onScroll, true)
        },
        beforeDestroy() {
          window.removeEventListener("scroll", this.onScroll, true)
        },
        methods: {
          onScroll(e) {
            this.windowTop = e.target.scrollTop;
          }
        }
        

        第三个参数: 您应该能够附加一个带有第三个参数 true 的文档级侦听器,以捕获所有元素上的滚动事件。看起来是这样的:

        document.addEventListener('scroll', function(e){ }, true);
        

        最后的 true 是重要的部分,它告诉浏览器在调度时捕获事件,即使该事件通常不会冒泡,例如更改、聚焦和滚动。

        【讨论】:

          【解决方案5】:

          我试图做一些事情,我只需要调用一个变量或函数来获取任何组件中的窗口滚动位置。所以为了实现这一点,我最终使用了 mixins。 这是我的代码。我正在使用 nuxt。

          在插件内部创建一个文件,例如。滚动位置.js

          import Vue from 'vue'
          
          Vue.mixin({
              data() {
                  return {
                      scrollPosition: window.scrollY
                  }
              },
              methods: {
                  get_scroll_position() {
                      window.addEventListener('scroll', () => {
                          this.scrollPosition = window.scrollY;
                      });
                      return this.scrollPosition
                  }
              }
          })
          

          在 nuxt.config.js 中

          plugins:['@/plugins/scroll-position.js']
          

          现在您可以在任何您想要的组件中使用 get_scroll_position() 像这样的

          :class="{'header_sticky':get_scroll_position()>=80}"
          

          【讨论】:

            猜你喜欢
            • 2019-02-19
            • 1970-01-01
            • 2018-07-12
            • 2020-05-23
            • 2018-01-20
            • 2019-03-09
            • 2021-07-15
            • 2013-03-31
            • 2018-04-18
            相关资源
            最近更新 更多