How to listen to the window scroll event in a VueJS component?

vue div scroll event
nuxt scroll event
vue wheel event
window listen to scroll
vue events
window scroll event not firing
mobile scroll event
typescript scroll event

I want to listen to the window scroll event in my Vue component. Here is what I tried so far:

<my-component v-on:scroll="scrollFunction">

With the scrollFunction(event) being defined in my component methods but it doesn't seem to work.

Anyone has any idea how to do this?


Actually I found a solution. I add an event listener on the scroll event when the component is created and remove the event listener when the component is destroyed.

export default {
  methods: {
    handleScroll (event) {
      // Any code to be executed when the window is scrolled
  created () {
    window.addEventListener('scroll', this.handleScroll);
  destroyed () {
    window.removeEventListener('scroll', this.handleScroll);

Hope this helps!

vue.js listen to scroll event · Issue #324 · vuejs/Discussion · GitHub, I actually found a solution by attaching the window scroll event to my component method like this: data () { return { scrolled: false }; }, methods:  You can easily listen to any scroll events. You can do it in your first component thats bound to your entry 'el'. In your mounted function just add an eventlister to window for scroll event. I do this for components that need to detect whether they are visible and in viewport.

In my experience, using an event listener on scroll can create a lot of noise due to piping into that event stream, which can cause performance issues if you are executing a bulky handleScroll function.

I often use the technique shown here in the highest rated answer, but I add debounce on top of it, usually about 100ms yields good performance to UX ratio.

Here is an example using the top-rated answer with Lodash debounce added:

import debounce from 'lodash/debounce';

export default {
  methods: {
    handleScroll(event) {
      // Any code to be executed when the window is scrolled
      this.isUserScrolling = (window.scrollY > 0);
      console.log('calling handleScroll');

  created() {
    this.handleDebouncedScroll = debounce(this.handleScroll, 100);
    window.addEventListener('scroll', this.handleDebouncedScroll);

  beforeDestroy() {
    // I switched the example from `destroyed` to `beforeDestroy`
    // to exercise your mind a bit. This lifecycle method works too.
    window.removeEventListener('scroll', this.handleDebouncedScroll);

Try changing the value of 100 to 0 and 1000 so you can see the difference in how/when handleScroll is called.

BONUS: You can also accomplish this in an even more concise and reuseable manner with a library like vue-scroll. It is a great use case for you to learn about custom directives in Vue if you haven't seen those yet. Check out

This is also a great tutorial by Sarah Drasner in the Vue docs:

How to detect body scroll? - Get Help, it will not work because this is body scroll not app scroll. You can do that in multiple components, each will listen for window scroll event. You can listen for a window event in Vue like this: methods: { onResize(event) { console.log('window has been resized', event) } }, mounted() { // Register an event listener when the Vue component is ready window.addEventListener('resize', this.onResize) }, beforeDestroy() { // Unregister the event listener before destroying this Vue instance window.removeEventListener('resize', this.onResize) }

Your requirements were on component but you ended with adding on body and not on component. Sure, you can do that on particular element as well but hey ...Here's what works directly with Vue custom components.

 <MyCustomComponent nativeOnScroll={this.handleScroll}>


<my-component v-on:scroll.native="handleScroll">

and define a method for handleScroll. Simple!

Creating Custom Scroll Directives, easeOut }) } return window. Attaching and removing scroll events to elements is a really good use case for this technique because just they are necessarily tied to the element and otherwise, we'd have to find the reference for it in the DOM. vue.js listen to scroll event #324. I actually found a solution by attaching the window scroll event to my component method like this: data {return

I've been in the need for this feature many times, therefore I've extracted it into a mixin. It can be used like this:

import windowScrollPosition from 'path/to/mixin.js'

new Vue({
  mixins: [ windowScrollPosition('position') ]

This creates a reactive position property (can be named whatever we like) on the Vue instance. The property contains the window scroll position as an [x,y] array.

Feel free to play around with this CodeSandbox demo.

Here's the code of the mixin. It's thoroughly commentated, so it should not be too hard to get an idea how it works:

function windowScrollPosition(propertyName) {
  return {
    data() {
      return {
        // Initialize scroll position at [0, 0]
        [propertyName]: [0, 0]
    created() {
      // Only execute this code on the client side, server sticks to [0, 0]
      if (!this.$isServer) {
        this._scrollListener = () => {
          // window.pageX/YOffset is equivalent to window.scrollX/Y, but works in IE
          // We round values because high-DPI devies can provide some really nasty subpixel values
          this[propertyName] = [

        // Call listener once to detect initial position

        // When scrolling, update the position
        window.addEventListener('scroll', this._scrollListener)
    beforeDestroy() {
      // Detach the listener when the component is gone
      window.removeEventListener('scroll', this._scrollListener)

Browser/Window Scroll event from within a Component, Simply add an event listener as soon as the component is mounted. If you are using vue <2.0 replace mounted with ready. export default{  Add event listeners in VueJS 2. How to listen for 'props' changes. 41. How to listen to the window scroll event in a VueJS component? 128.

I think the best approach is just add ".passive"


Vue cannot listen for scroll events, It is invalid to listen for scroll events on a component, and there is no scroll operation or trigger. The v-on and window addEventListener methods used to listen  Listening to the kebab-cased version will have no effect: <!-- Won't work --> < my-component v-on:my-event = "doSomething" > </ my-component > Unlike components and props, event names will never be used as variable or property names in JavaScript, so there’s no reason to use camelCase or PascalCase.

Scroll Tracking in Vue Applications - Some gotchas, pageYOffset + window.innerHeight) ); } // The main handler of highlighting appropriate nav items. Vue.component("navigation", { We can use the v-on directive to listen to DOM events and run some JavaScript when they’re triggered. The button above has been clicked 0 times. The logic for many event handlers will be more complex though, so keeping your JavaScript in the value of the v-on attribute isn’t feasible. That’s why v-on can also accept the name of a method

Hide Navbar on Scroll Down in Vue - Taha Shashtari, We'll only need a single component for this demo: App.vue . Now, when the page is loaded, we need to listen for the scroll event on window . window.scrollX window.scrollY window.innerHeight window.innerWidth. At this moment, there’s no way in VueJS to natively “watch” a window property or making it reactive. I couldn’t find a way to make scrollY reactive in many places efficiently in my application. I also didn’t want to add boilerplate like the ones below to each of my

How do you listen to the scroll event on the <body> element? : vuejs, I used to be able to have my vue app attached the the body element, so i could has position=fixed to be an artificial window onto my app (with overflow=scroll). When listening for keyboard events, we often need to check for common key codes. Vue.js provides a special key filter that can only be used with v-on directives. It takes a single argument that denotes the key code to check for: