vue-aware

Optimized and easy way to manage events across Vue.js components.

Usage no npm install needed!

<script type="module">
  import vueAware from 'https://cdn.skypack.dev/vue-aware';
</script>

README

vue-aware

Optimized and easy way to manage events across Vue.js components.

stability-wip NPM version CircleCI Coverage Status Commitizen friendly Conventional Commits License

Description

vue-aware allows your components to easily listen to "common global" events such as:

  • scroll
  • viewport resize
  • appear on viewport
  • request animation frame

Another kind of bus event?

What makes vue-aware special is how it manages events for you.
vue-aware will create as LESS listeners as possible and ONLY when some components need it!
Which is good performance wise…


Installation

npm install --save vue-aware

Import

import Vue from 'vue';
import VueAware from 'vue-aware';

Vue.use(VueAware);

Browser

<script src="vue.js"></script>
<script src="https://unpkg.com/thierrymichel/vue-aware"></script>

vue-aware should be auto-installed. If not, use Vue.use(VueAware).

Usage

General

  1. Simply add the v-aware directive to your element(s).
  2. Define a handler for an event (appear, raf, scroll, viewport):
  • @[event]="handler" or
  • v-on:[event]="handler" or
  • v-aware="{ [event]: { callback: handler } }"

🚨Components (vs elements) only accept callback property with v-aware directive (@ or v-on won't work)

Note: callback property has precedence over @ or v-on directive…

Example (scroll)

<div v-aware @scroll="scrollHandler"></div>
<div v-aware v-on:scroll="scrollHandler"></div>
<div v-aware="{ scroll: { callback: scrollHandler }}"></div>

Appear

appear uses the IntersectionObserver API. If it is incompatible with your browser support, you can polyfill it.

appear will let you know if your element is:

  • partially in viewport
  • fully in viewport
  • positionned on top, bottom or center of the viewport

Like IntersectionObserver, it accepts options:

  • root (HTMLElement, default is browser viewport)
  • rootMargin (CSS margin prop, with % or px, default is 0px 0px 0px 0px)
  • threshold (related to target's visibility, number or number[], default is [0, 1])

and an extra one:

  • once (your callback is only trigger once, default false)

Example

<!-- no options -->
<div v-aware @appear="appearHandler"></div>
<!-- full options -->
<div
  v-aware="{
  appear: {
    root: document.querySelector('.foo'),
    rootMargin: '-25% 0px',
    threshold:  [0, 0.25, 0.5, 0.75, 1],
    once: true,
  }}"
  @appear="appearHandler"
></div>
export default {
  methods: {
    appearHandler(isInViewport, isFullyInViewport, position, context) {},
  },
};

Raf (requestAnimationFrame)

Use requestAnimationFrame to trigger your handler.
There is no options.

Example

<div v-aware @raf="rafHandler"></div>
export default {
  methods: {
    rafHandler(delta, now, context) {},
  },
};

Scroll

Gives you the scroll position (x and y).
You can throttle or debounce it (read more).

Example

<!-- no options -->
<div v-aware @scroll="scrollHandler"></div>
<!-- full options -->
<div
  v-aware="{
  scroll: {
    throttle: 250,
    debounce: 50,
  }}"
  @scroll="scrollHandler"
></div>
export default {
  methods: {
    scrollHandler(scrollX, scrollY, context) {},
  },
};

Viewport

When a window resize is detected.
It gives you the width and height of the viewport + ratio (width/height).
You can throttle or debounce it (read more).
By default, it is throttled (150ms).

Example

<!-- no options -->
<div v-aware @viewport="viewportHandler"></div>
<!-- full options -->
<div
  v-aware="{
  viewport: {
    throttle: 250,
    debounce: 50,
  }}"
  @viewport="viewportHandler"
></div>
export default {
  methods: {
    viewportHandler(width, height, ratio, context) {},
  },
};

How to contribute

If you want to report a bug or if you just want to request for a new feature/improvement, please follow those instructions before.

Thanks for taking time to contribute to vue-aware :tada: :+1: