background

Vue3 is known to have come of age, and Vue3 recommends the use of composite apis, that is, switching from class programming to functional programming, logic to setup syntax sugar, and setup as the entry point to the composite Api. In React, AHooks are the comprehensive and useful Hooks library, but I couldn’t find one in Vue3, so I decided to write a set of Hooks libraries. With the V3Hooks library in place, we’ll introduce a few hooks, and if that helps you get a Star support.

use

Let’s look at some common Hook uses

useRequest

UseRequest is a Hook for managing asynchronous requests. It encapsulates common request initiation methods in requirements and speeds up your daily development with the following features:

  • Automatic request/manual request
  • SWR(stale-while-revalidate)
  • Cache/preload
  • Screen focus rerequested
  • polling
  • Image stabilization
  • The throttle
  • Rely on request
  • mutation
  • loading delay

Request Initiation Mode

If the Service is object,useRequest will use Fetch to send network requests

import { useRequest } from 'v3hooks';
const { data } = useRequest(
    {
    url: 'http://xxx.xx.com/api/userInfo',
    method: 'POST'
    }
);
Copy the code

If service is async,useRequest calls this function to send network requests

import { useRequest } from 'v3hooks'; const { data } = useRequest( () => { return axios.post( `http://xxx.xx.com/api/userInfo` ); });Copy the code

Based on the request

import { useRequest } from 'v3hooks'; const { data, loading } = useRequest( () => { return axios.post( `http://xxx.xx.com/api/userInfo` ); }); watchEffect(()=>{ console.log( data? .value ); })Copy the code

In this example, useRequest receives an asynchronous function that is automatically triggered when the component is first loaded. In addition, useRequest automatically manages the loading and data states of asynchronous requests. You can use data and loading to fulfill your needs

Because the returned data is reactive, retrieving data.value from js needs to be used in watchEffect, but not in template.

Manual trigger

const { data, run, loading } = useRequest(
    () => {
        return axios.post(
            `http://xxx.xx.com/api/userInfo`
        );
    },
    {
        manual: true
    }
);
Copy the code

With options.manual = true, asynchronous functions are triggered only when run is called manually.

polling

const { data, loading } = useRequest(
    () => {
        return axios.post(
            `http://xxx.xx.com/api/userInfo`
        );
    },
    {
        pollingInterval: 1000
    }
);
Copy the code

You can set options.pollingInterval to enter the polling mode and trigger function execution periodically.

Rely on request

import { onMounted, ref } from 'vue'

const isReady = ref(false);
const { data, loading } = useRequest(
    () => {
        return axios.post(
            `http://xxx.xx.com/api/userInfo`
        );
    },
    {
        ready: isReady
    }
);
onMounted(() => {
    isReady.value = true;
})
Copy the code

Requests are only initiated when options.ready is true. Serial requests, dependent requests, and so on can be implemented with this feature.

Image stabilization

const { data, loading } = useRequest(
    () => {
        return axios.post(
            `http://xxx.xx.com/api/userInfo`
        );
    },
    {
        debounceInterval: 1000
    }
);
Copy the code

To enter the anti-shake mode, set options.debounceInterval. If run is frequently triggered, requests are made using the anti-shake policy.

The throttle

const { data, loading } = useRequest(
    () => {
        return axios.post(
            `http://xxx.xx.com/api/userInfo`
        );
    },
    {
        throttleInterval: 1000
    }
);
Copy the code

By setting options.throttleInterval, you can enter throttling mode. If run is frequently triggered at this point, the request will be throttled.

Cache & SWR

const { data, loading } = useRequest(
    () => {
        return axios.post(
            `http://xxx.xx.com/api/userInfo`
        );
    },
    {
        caccacheKey: 'mock1'
    }
);
Copy the code

If options.cacheKey is set, useRequest will cache the current request end data. The next time a component initializes, if there is cached data, we will return cached data first, and then send a new request behind it, which is the ability of SWR. You can set the time for caching data to be reclaimed using cacheTime, and you can set the time for caching data to be kept fresh using staleTime.

preload

const { data, loading } = useRequest(
    () => {
        return axios.post(
            `http://xxx.xx.com/api/userInfo`
        );
    },
    {
        caccacheKey: 'mock1'
    }
);
Copy the code

Requests for the same cacheKey are shared globally, meaning you can request data in advance. Subsequent requests return preloaded data in advance. This feature facilitates preloading.

Screen focus rerequested

const { data, loading } = useRequest(
    () => {
        return axios.post(
            `http://xxx.xx.com/api/userInfo`
        );
    },
    {
        refreshOnWindowFocus: true,
        focusTimespan: 2000
    }
);
Copy the code

If you set the options. RefreshOnWindowFocus = true, then refocus the browser window and revisible, will initiate the request again. You can set the request interval by setting options.focusTimespan. Default: none.

mutation

const { data, mutate } = useRequest( () => { return axios.post( `http://xxx.xx.com/api/userInfo` ); }); < button type = "button" @ click = {() = > mutate ({code: '1', MSG: 'test'})} > mutation test < / button >Copy the code

You can modify data directly through mutate.

Loading Delay

const { data, loading } = useRequest(
    () => {
        return axios.post(
            `http://xxx.xx.com/api/userInfo`
        );
    },
    {
        loadingDelay: 300
    }
);
Copy the code

By setting options.loadingDelay, you can delay the time when loading becomes true to prevent blinking.

refreshDeps

This requirement is often encountered during development, and when some state changes, we need to re-execute the asynchronous request. UseRequest is a convenient way to do this.

import { onMounted, ref } from 'vue'

const random = ref(1);
const { data, loading } = useRequest(
    () => {
        return axios.post(
            `http://xxx.xx.com/api/userInfo`
        );
    },
    {
        refreshDeps: [ random ]
    }
);

setInterval(()=>{
    random.value = Math.random()
},1000)
Copy the code

When random changes in the example, service is re-executed.

useVirtualList

Hook of long list virtualization list, used to solve the problem of slow first screen rendering and scrolling lag when rendering massive data.

GIF demo

The GIf image is large. Please wait patiently for it to load

Based on using

<template> <div class="hello"> <button style="margin-top: 30px" type="button" @click="handleVirtualScrollTo" > scroll to </button> <div :ref="containerProps.ref" @scroll="containerProps.onScroll" style="height: 300px; overflow: auto; border: 1px solid #cccccc" > <div :style="wrapperStyle"> <div v-for="active in list" :key="active" style=" height: 59px; border-bottom: 1px solid #cccccc; background-color: white; " > {{ active }} </div> </div> </div> </div> </template> <script lang="ts"> import { useVirtualList } from "v3hooks"; export default { setup() { const { list, wrapperStyle, containerProps, scrollTo } = useVirtualList( Array.from(Array(99999).keys()), { itemHeight: 60, overscan: 10, } ); const handleVirtualScrollTo = () => { scrollTo(22); }; return { list, wrapperStyle, containerProps, handleVirtualScrollTo, }; }}; </script>Copy the code

UseVirtualList takes an array and exports a virtualized list configured with elements. See the Api for details

useTextSelection

Hook to get the current text content and location selected by the user in real time.

UseTextSelection takes an HTMLElement and exports the selected text and location information.

GIF demo

Based on using

<template> <div style="text-align: center"> <p ref="p"> 123111111111111 aaaaaaaaaaabbbbbbbbbbb eeeeeeeeeeeeeeee < / p > < p > the selected value: {{text}} < / p > < p > location: the rect: {{ rect }}</p> <p>left: {{ rect.left }}</p> </div> </template> <script lang="ts"> import { useTextSelection } from "v3hooks"; export default { setup() { const { text, rect } = useTextSelection(); return { text, rect }; }}; </script>Copy the code

No value is passed. The default is Document, and any selectable text on the page will be evaluated

Listen for specific area text selections

<template> <div style="text-align: center"> <p ref="p"> 123111111111111 aaaaaaaaaaabbbbbbbbbbb eeeeeeeeeeeeeeee < / p > < p > the selected value: {{text}} < / p > < p > location: the rect: {{ rect }}</p> <p>left: {{ rect.left }}</p> </div> </template> <script lang="ts"> import { ref } from 'vue'; import { useTextSelection } from "v3hooks"; export default { setup() { const p = ref(); const { text, rect } = useTextSelection(p); return { text, p, rect }; }}; </script>Copy the code

P tags that pass a value of Ref listen only for a specific region.

useQRCode

A Hook for generating a QR code.

GIF demo

Based on using

</div> <img: SRC ="state" Alt =""> </div> </template> <script lang="ts"> import {  ref } from 'vue'; import { useQRCode } from ".. /.. /.. /dist/index.js"; const logo = require('.. /.. /assets/logo.png') export default { setup() { const text = ref<string>('https://www.baidu.com/') const state = useQRCode(text,{ logo: logo.default, colorDark: '#000000' }); setTimeout(()=>{ text.value = 'https://www.acfun.cn/' },2000) return { state }; }}; </script>Copy the code

UsQRCide can accept a static URL or a URL wrapped by Ref. When the Ref value changes, the QR code will change with the content.

useNetwork

A Hook to get the current state of the network.

Images demonstrate

Based on using

<template> <div class="hello" style="display:flex; align-items:flex-start;" > <p> Network status :{{state}}</p> </div> </template> <script lang="ts"> import {useNetwork} from "v3hooks"; Export default {setup() {// Get a const state in query = useNetwork(); // useVirtualList test return {state}; }}; </script>Copy the code

UseNetwork Returns network status information

At the end

There are a number of Hooks in the V3Hooks section that you can use. See the documentation and link to GitHub to learn how to use them.