mr.incredible
mr.incredible

Reputation: 4165

Vue: scroll listener issue

I've started to use Vue CLI but ran into a problem of handling window scroll position.

Just copied this example from Vue docs but it doesn't work.

This is my Nav.vue component:

<template>
   <nav v-scroll="handleScroll"></nav>
</template>

<script>
export default {
   name: 'my-nav',
   data() {
      return {
         scrolled: false
      }
   },
   directives: {
      scroll: {
         inserted: function (el, binding) {
            let f = function (evt) {
               if (binding.value(evt, el)) {
                  window.removeEventListener('scroll', f)
               }
            }
         }
      }
   },
   methods: {
      handleScroll: function (evt, el) {
         if (window.scrollY > 50) {
            el.setAttribute(
               'style',
               'opacity: .5; background-color: red;'
            )
         }
         return window.scrollY > 100
      }
   }
}
</script>

<style lang="scss" scoped>
   nav {
      position: fixed;
      width: 100%;
      height: 68px;
      background-color: white;
      z-index: 100;
   }
</style>

An error occurs in this case:

error  in ./src/components/Nav.vue

Module Error (from ./node_modules/eslint-loader/index.js):
error: 'f' is assigned a value but never used (no-unused-vars)

Also I searched other approaches how to handle scroll event but none of the worked.

In this case handleScroll method is just ignored:

<template>
   <nav v-bind:class="{ hidden: scrolled}"></nav>
</template>

<script>
export default {
   name: 'my-nav',
   data() {
      return {
         scrolled: false
      }
   },
   methods: {
      handleScroll: function () {
         this.scrolled = window.scrollY > 150;
      }
   },
   created: function () {
      window.addEventListener('scroll', this.handleScroll);
   },
   destroyed: function () {
      window.removeEventListener('scroll', this.handleScroll);
   }
}
</script>
<style>
.hidden {
  opacity: .3;
}
</style>

It seemed to me that such simple things are much easier to resolve with Vue but I was wrong.

How to make scroll event work properly?

Upvotes: 0

Views: 370

Answers (1)

Terry
Terry

Reputation: 66093

Your second approach should work, with one little caveat: you are not setting scrolled in the component data properly: you should be using this.scrolled, i.e.:

handleScroll: function () {
   this.scrolled = window.scrollY > 150;
}

See proof-of-concept example:

new Vue({
  el: '#app',
  data() {
    return {
      scrolled: false
    }
  },
  methods: {
    handleScroll: function() {
      this.scrolled = window.scrollY > 150;
    }
  },
  created: function() {
    window.addEventListener('scroll', this.handleScroll);
  },
  destroyed: function() {
    window.removeEventListener('scroll', this.handleScroll);
  }
});
body {
  min-height: 200vh;
}

nav {
  position: fixed;
  top: 20px;
  left: 20px;
}

.hidden {
  opacity: 0.3
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <nav v-bind:class="{ hidden: scrolled }">NAV</nav>
</div>

Upvotes: 1

Related Questions