Skip to main content
Home

Vue conditional event binding

Disclaimer: this is a short elaboration on this StackOverflow answer.

There’s no way I could imagine a component running in a modern app without having at least one event listener attached to some element. The beautiful part is that Vue is generally pretty smart about those, they properly get cleaned up once the component is destroyed and they don't pile up cluttering the memory and slowing everything down.

Everything is great until you need more fine tuning. I’m going to give here a simple idea for how to conditionally add and remove event listeners, over the lifetime of a component.

Let’s say you need to handle the click event for a button, but only when the screen is bigger than 600px. Here’s how we can achieve that pretty easily.

const IS_MOBILE_DEVICE = window.outerWidth < 600;

export default {
  name: 'Wrapper',

  methods: {
    handleClick() {
      // Do awesomeness
    },
  },

  render(h) {
    return h(
      'div',
      IS_MOBILE_DEVICE
        ? {}
        : {
            on: { click: this.handleClick },
          }
    );
  },
};

Looking at this snippet, we see a raw render function, without any syntactic sugar. This example looks a lot better when using JSX.

export default {
  name: 'Wrapper',

  render() {
    return (
      <div
        {...{
          on: IS_MOBILE_DEVICE
            ? {}
            : {
                click: () => {
                  // Do awesomeness
                },
              },
        }}
      />
    );
  },
};

With a bit of help from matchMedia() magic we could build a pretty neat demo.

The demo will dynamically add and remove the click event as the user resizes the screen, with a very performant listener, handled by matchMedia().

Of course, this is pretty absurd most of the time, but it only demonstrates that the possibilities are endless!

Please note that the click handler only works when the screen is larger than 600px. Resizing the main browser window will properly work too.

Enjoy and have fun!

Profile picture

Andrei Glingeanu's notes and thoughts. You should follow him on Twitter, Instagram or contact via email. The stuff he loves to read can be found here on this site or on goodreads. Wanna vent or buy me a coffee?