Skip to content

Latest commit

History

History
executable file
117 lines (95 loc) 路 2.75 KB

useIntersection.md

File metadata and controls

executable file
117 lines (95 loc) 路 2.75 KB

useIntersection

Vue function that tracks the changes in the intersection of a target element with an ancestor element or with a top-level document's viewport.

It is based on the Intersection Observer API.

Reference

function useIntersection(
    elRef: Ref<null | HTMLElement>,
    options?: IntersectionObserverInit,
    runOnMount?: boolean
): {
    observedEntry: Ref<IntersectionObserverEntry | null>;
    start: () => void;
    stop: () => void;
};

Parameters

  • elRef: Ref<null | HTMLElement> the element to observe
  • options: IntersectionObserverInit the IntersectionObserver options
  • runOnMount: boolean whether to observe the element on mount, true by default

Returns

  • observedEntry: Ref<IntersectionObserverEntry | null> the observed entry
  • start: Function the function used for start observing
  • stop: Function the function used for stop observing

Usage

First we have to define the intersection component, named UseIntersectionElDemo.vue.

<template>
  <div ref="elRef" class="el" :class="elClass">
    <slot></slot>
  </div>
</template>

<script lang="ts">
  import Vue from 'vue'
  import { ref, watch } from '@src/api'
  import { useIntersection } from 'vue-use-kit'

  export default Vue.extend({
    name: 'UseIntersectionElDemo',
    setup() {
      const options = {
        root: null,
        rootMargin: '0px 0px -30px',
        threshold: 1.0
      }

      const elRef = ref(null)
      const elClass = ref('')
      const { observedEntry } = useIntersection(elRef, options)
      watch(() => {
        if (!observedEntry.value) return
        const isVisible = observedEntry.value.intersectionRatio === 1
        elClass.value = isVisible ? '-is-visible' : ''
      })

      return {
        elRef,
        elClass
      }
    }
  })
</script>

Then we can call it in a loop in the parent component UseIntersectionDemo.vue.

<template>
  <div>
    <div class="el-wrap" v-for="n in tot">
      <use-intersection-el-demo />
    </div>
  </div>
</template>

<script lang="ts">
  import Vue from 'vue'
  import UseIntersectionElDemo from './UseIntersectionElDemo.vue'

  export default Vue.extend({
    name: 'UseIntersectionDemo',
    components: { UseIntersectionElDemo },
    setup() {
      const tot = new Array(100)
      return { tot }
    }
  })
</script>

<style>
  .el-wrap {
    margin: 200px 0;
  }

  .el {
    width: 40px;
    height: 40px;
    background: red;
    transition: 0.3s ease-in-out;
  }

  .el.-is-visible {
    background: green;
  }
</style>