Watch window.scrollY changes in Vuejs

2019-07-24 18:11发布

问题:

I have a very simple app, that has 2 components: the App.vue and another component, Home.vue where I hold the rest of the structure of the app: a sticky header and some sections with anchors to scroll to.

I want to apply a class to the sticky header to minimize the logo while the page is scrolled. So I thought I'd watch for any changes in window.scrollY. So if scrollY is greater than 0, apply some class that minimizes the logo.

I tried to listen to scroll events in my component, but that didn't go very far. In this discussion here, a very good solution is provided, but I don't know where to place the scroll event. https://github.com/vuejs/Discussion/issues/324

So, I thought the most fitting solution would be to create a data property, assign it the window.scrollY figure and then watch for changes in its value. Unfortunately, the watcher is never triggered. So now I'm stuck. The code is:

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

Any ideas of what I might be doing wrong?

回答1:

window properties can't be used reactively like that. Instead, you'd have to listen to the window's scroll event and respond accordingly:

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:

You can use the mounted() method to add your event listener to the window object like this:

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>