Vueuse /core implements lazy loading of component data

  • Purpose: To load data when the component enters the viewable area.
  • Core: Use@vueuse/coreIn theuseIntersectionObserverTo listen for components entering the view area
  • Note: this can only be done in conjunction with vue3.0’s composite API.

UseIntersectionObserver describes the function

const { stop } = useIntersectionObserver(target, fn, options)
Copy the code
  • target: represents the DOM element being listened on. It must be a DOM container and a VUe3.0 bound DOM object
  • fnThe: callback function notifies the listener of the action (the first parameter of the callback function)isIntersectingIndicates that the monitored element is already visible.
  • options: Configuration options

Basic usage

// stop is the action of stopping to see whether to enter or move out of the viewable area
const { stop } = useIntersectionObserver(target,([{ isIntersecting }], observerElement) = > {
    // It can be judged by isIntersecting and then do business
  },
  // Whether isIntersecting enters the visible area. If true, it enters and if false, it moves out
  // observerElement the DOM to observe
)
Copy the code

Implement lazy loading of component data

// MyComponent.vue

<template>
  <div ref="target">
      <div>
          <ul>
            <li v-for="item in goods" :key="item.id">
              <RouterLink :to="`/${item.id}`">
                <img :src="item.picture" alt="" />
                <p>{{ item.name }}</p>
                <p>{{ item.price }}</p>
              </RouterLink>
            </li>
          </ul>
      </div>
  </div>
</template>

<script>
import { ref } from 'vue'
/ / incoming @ vueuse/core
import { useIntersectionObserver } from '@vueuse/core'
import { findNewAPI } from '@/api'

export default {
  name: 'MyComponent'.setup() {
    const goods = ref([])
    const target = ref[null]
    const { stop } = useIntersectionObserver(target, ([{ isIntersecting }]) = > {
      if(isIntersecting) {
        // If isIntersecting is true, target enters the viewable area and then initiates the request
        findNewAPI().then(ret= > goods.value = ret.data)
        // Unlisten for the component to enter the view area
        stop()
      }
    })
    return { goods, target }
  }
}
</script>
Copy the code

Lazy loading of data has been implemented in the MyComponent at this point, but in a project this method can be wrapped to make it easier to use in multiple places, usually in SRC /hooks/index.js

// src/hooks/index.js
import { ref } from 'vue'
import { useIntersectionObserver } from '@vueuse/core'

export const useLazyData = (apiFn) = > {
  const goods = ref([])
  const target = ref[null]
  const { stop } = useIntersectionObserver(target, ([{ isIntersecting }]) = > {
    if(isIntersecting) {
      // If isIntersecting is true, target enters the viewable area and then initiates the request
      apiFn().then(ret= > goods.value = ret.data)
      // Unlisten for the component to enter the view area
        stop()
     }
   })
  return { goods, target }
}
Copy the code

In the component

// MyComponent.vue

<template>
  <div ref="target">
      <div>
          <ul>
            <li v-for="item in goods" :key="item.id">
              <RouterLink :to="`/${item.id}`">
                <img :src="item.picture" alt="" />
                <p>{{ item.name }}</p>
                <p>{{ item.price }}</p>
              </RouterLink>
            </li>
          </ul>
      </div>
  </div>
</template>

<script>
import { findNewAPI } from '@/api'
import { useLazyData } from '@/hooks'
export default {
  name: 'MyComponent'.setup() {
    const { goods, target } = useLazyData(findNewAPI)
    return { goods, target }
  }
}
</script>
Copy the code

Step after Use

  • In the outermostdomAdd to elementrefProperty and the value istarget
  • The introduction ofhooksThe encapsulation ofuseLazyDatamethods
  • EncapsulateapiFunction touseLazyDataMethod and receivegoods, target
  • At this time:goodsRender the page for the requested data,targetref