JSPM

vue3-deferred-content

1.0.8
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 312
  • Score
    100M100P100Q94228F
  • License MIT

A Vue3 component to detect when HTML element or lazy component is becoming visible/hidden on the page.

Package Exports

  • vue3-deferred-content

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (vue3-deferred-content) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

vue3-deferred-content

A Vue3 component to detect when lazy component or HTML element is becoming visible/hidden on the page. The intersection can be observed once or listened by callback.

🚀 Features

  • 🔗 0 dependencies: No worry about your bundle size
  • Type Strong: Written in Typescript
  • 📦 Size: ~27kb

Live demo 🎉

📦 Installation

$ npm i vue3-deferred-content
# or
$ yarn add vue3-deferred-content

📎 How to use?

main.js:

import { createApp } from 'vue'
import App from './App.vue'
import VueDeferredContent from 'vue3-deferred-content'

const app = createApp(App)
const options = {
  name: 'lazyContent',  // by default: deferred
  
  // by default for all components
  rootMargin: '0px',        // string
  threshold: 0,             // number | number[]
}     
app.use(VueDeferredContent, options)
app.mount('#app')

Examples

  1. Standard example with callbacks.
<b>status: {{status}}</b>
<lazy-content
    :auto-hide="false"
    @enter="enterElement"
    @leave="leaveElement"
    @change="changeIntersect"
    @disconnect="disconnect"
>
    <img src="http://placekitten.com/360/280" alt="kitten">
    <p>Number of changes: {{changeCount}}</p>
</lazy-content>
export default defineComponent({
  name: 'Example1',
  data:() => ({
    changeCount: 0,
    status: '🙈 Leave',
  }),
  methods: {
    enterElement(target) {
      this.status = '🐵 Enter'
      console.log(this.status, target)
    },
    leaveElement(target) {
      this.status = '🙈 Leave'
      console.log(this.status, target)
    },
    changeIntersect(target) {
      this.changeCount++
      console.log('Change', target)
    },
    disconnect() {
      console.log('Disconnect')
    },
  },
})
  1. Called once after first enter.
<lazy-content
  :once="true"
  @change="changeIntersect"
>
  <img src="http://placekitten.com/g/361/281" alt="kitten 2">
  <p>Number of changes: {{changeCount}}</p>
</lazy-content>
export default defineComponent({
  name: 'Example2',
  data:() => ({
    changeCount: 0,
  }),
  methods: {
    changeIntersect(target) {
      this.changeCount++
      console.log('Change', target)
    },
  },
})
  1. Calling the module without callbacks. Lazy load image.
<lazy-content>
  <img src="https://placekitten.com/362/282" alt="kitten 3">
</lazy-content>
  1. Lazy load image and Transition.
<lazy-content>
  <transition name="fade" :appear="true">
    <!-- This DIV tag is required for this example and I don't know why. :( -->
    <div>
      <img src="https://placekitten.com/400/300" alt="kitten 4">
    </div>
  </transition>
</lazy-content>
.fade-enter-active,
.fade-leave-active {
    transition: opacity 0.8s ease;
}

.fade-enter-from,
.fade-leave-to {
    opacity: 0;
}
  1. Lazy load image and Transition group.
<lazy-content>
  <transition-group name="list" :appear="true">
      <span v-for="(item, index) in items" :key="item" class="list-item" :style="`transition-delay: ${index * 250}ms;`">
        <img :src="item" alt="kitten 5">
      </span>
  </transition-group>
</lazy-content>
export default defineComponent({
  name: 'Example5',
  data:() => ({
    items: [
      'https://placekitten.com/360/280',
      'https://placekitten.com/361/281',
      'https://placekitten.com/362/282',
    ]
  })
})
.placeholder {
    display: flex;
    flex-direction: row;
    justify-content: space-around;
}

.list-item {
    width: 30%;
}

.list-enter-active,
.list-leave-active {
    transition: all 1s ease;
}

.list-enter-from,
.list-leave-to {
    opacity: 0;
    transform: translateY(30px);
}
  1. Async Component and Transition.
<lazy-content
  :once="true"
>
  <transition name="fade" :appear="true">
    <AsyncComponent/>
  </transition>
</lazy-content>
export default defineComponent({
  name: 'Example6',
  components: {
    AsyncComponent: defineAsyncComponent(() => import('./AsyncComponent.vue')),
  },
})
.fade-enter-active,
.fade-leave-active {
    transition: opacity 15s ease;
}

.fade-enter-from,
.fade-leave-to {
    opacity: 0;
}

TODO

  • Test

License

MIT License

Copyright (c) :suspect: @yesworld