More articles

preface

Following on from the previous article, here is useAsync

introduce

UseAsync is a unified encapsulation of interface requests. It receives a promise request, returns a data store to the interface, and uses a try catch to catch server or syntax errors

Based on using

Request is a PROMISE request. Result the receiving interface returns data


const { result } = useAsync({ request, isLoading: false })
Copy the code

Initialization is not called


const { result } = useAsync({ request, init: false.isLoading: false })
Copy the code

The default take ginseng


const { result } = useAsync({ request, params: { id: 1}})Copy the code

Start loading

By default, loading is enabled. Most service scenarios require loading. If no loading is required, set isLoading to False


const{result, loading} = useAsync({request})Copy the code

Chain calls


const { doResult } = useAsync({ request })

const getList = () = > doResult(params).then(({code, params, data, message}) = > console.log('ok'))
Copy the code

The scene of a

External loading is required for editing and adding a shared popover

When editing, modifying, or deleting a shared popover, loading is not applicable to the loading thrown by useAsync. Therefore, external loading should be used to handle the loading state through the callback function exposed by useAsync


// The definition of loading can be customized
const loading = ref(false)
// You can use useLoading, which is similar to the react-hooks approach. It has two main benefits:
// 1. Update data entry is clear, all data is updated by checkLoading method
// 2. The data flow is clear, and the loading update is in useLoading
import useLoading from '@/hooks/useLoading'
const { loading, checkLoading } = useLoading()
// preCallback: callback before calling the interface
// successCallBack: Successful callback
// errorCallBack: catch the errorCallBack
/ / new
useAsync({
  request: add,
  isLoading: false.preCallback: () = > checkLoading(true),
  errorCallBack: () = > checkLoading(false),
  successCallBack: () = > checkLoading(false)})/ / edit
useAsync({
  request: edit,
  isLoading: false.preCallback: () = > checkLoading(true),
  errorCallBack: () = > checkLoading(false),
  successCallBack: () = > checkLoading(false)})Copy the code

Scenario 2

Data is asynchronously obtained from the drop-down list


// Formstate. setConfig is a method to update the drop-down box data. If you don't know userForm, you shouldn't worry about this
// successCallBack is a subsequent action after the data has been obtained, where the action is one thing, such as updating the drop-down box, indicating a successful commit, triggering a table update, and so on
useAsync({
  request,
  isLoading: false.successCallBack: ({ code, data }) = > code === '0' && formState.setConfig('users'.'options', data || [])
})
Copy the code

Scenario 3

The data returned by the interface does not meet requirements

This simply means that the data does not meet the requirements. If the data does not meet the requirements, the callback can get the original data returned by the interface and process the original data, but the returned data should meet the {code, data, message} format

The default processing of data returned by the interface is as follows (by convention) :


// defaultCallBack is the built-in default processing of the data returned by the interface
const defaultCallBack = (res = {}) = > {
  // Res is the raw data returned by the interface
  if(! res)return {}
  const { data: { code, data, message } } = res || {}
  return {
    code,
    data,
    message
  }
}
Copy the code

Actual case:


// Parameter callback
const callback = res= > {
  const { data: { data } } = res || {}
  const result = Object.prototype.toString.call(data) === '[object Array]' ? data
  : data && data.pagedRecords ? data.pagedRecords
    : []
  // Return data in {data, code, message} format
  return {
    data: result
  }
}
// Get and process the data
const { result: dataSource, loading } = useAsync({ request, callback })
Copy the code

Scenario 4

Passive trigger

For example: Query


const { doResult } = useAsync({ request, init: false })

const searchHandle = params= > doResult(params)
Copy the code

Scene five

The action is triggered after the interface succeeds

For example, update the table after the form is submitted successfully

const { doResult } = useAsync({
  request,
  init: false.successCallBack: ({ code, params, data }) = > {
    code === '0' && Message.success('Add successful')
    code === '0' && emit('successHandle')
    code === '0' && doSomethings(params, data)
  }
})

const addHandle = params= > doResult(params)
Copy the code

The ginseng

parameter instructions type An optional value The default value
request Interface request Promise
params The default parameters Object
init Whether to initialize the call Boolean true
isLoading Whether to Enable loading Boolean true
preCallback Callback before calling the interface Function
callback Raw data processing callbacks, usually only for data processing Function(res)
successCallBack An action callback is triggered after the interface succeeds and data processing is complete Function({ code, data, message, params } )
errorCallBack Catch error callbacks, syntax errors, server failures, etc Function

Callback Params

After using callback to process data, the data should be returned in the following format: {code, data, message}

parameter instructions type An optional value The default value
res Raw data returned by the interface

SuccessCallBack Params

If the callback function is defined, the data returned by the user-defined callback function shall prevail

parameter instructions type An optional value The default value
code Status code
data Processed data
message Message returned by the interface
params The input parameter for the request

The ginseng

parameter instructions type An optional value The default value
loading Load state (not thrown if isLoading is false) Boolean false
result The data returned and processed by the receiving interface (responsive) null
doResult Triggers the interface call and updates the Result Function(params) null

DoResult Params

parameter instructions type An optional value The default value
params Interface into the reference Object {}

The source code

The processing of the returned data part of the interface is somewhat businesslike

import { ref } from '@vue/composition-api'
import useLoading from './useLoading'

/** * Scenarios: useAsync * is not required for interface calls or promise/hooks encapsulation@param Request Interface request *@param Params takes * by default@param Init Whether to initialize the call *@param IsLoading Whether the loading state is provided. You do not need to set isLoading to False. Otherwise, the loading state will be saved in the memory@param PreCallback preCallback *@param Callback Specifies the data processing callback after obtaining data@param SuccessCallBack Successful callback *@param ErrorCallBack errorCallBack */

const defaultCallBack = (res = {}) = > {
  if(! res)return {}
  const { data: { code, data, message } } = res || {}
  return {
    code,
    data,
    message
  }
}

export default ({
  request,
  params = {},
  init = true,
  isLoading = true,
  preCallback = null,
  callback = defaultCallBack,
  successCallBack = null,
  errorCallBack = null= > {})// Record the result
  const result = ref(null)

  // Whether to enable default loading
  const {
    loading,
    checkLoading
  } = isLoading ? useLoading() : {}

  const doResult = async (searchParams = {}) => {
    try {
      // The default processing is loading
      checkLoading && checkLoading(true)
      // Pre-callback
      preCallback && preCallback()
      const res = awaitrequest({... params, ... searchParams})// The default processing is loading
      checkLoading && checkLoading(false)
      // Get interface result processing
      const data = callback ? callback(res) : res
      // Store the processing interface for external acquisition
      result.value = data.data ?? null
      // Successful callback
      successCallBack && successCallBack(data ? { ...data, params: {... params, ... searchParams} } : {})return data ? { ...data, params: {... params, ... searchParams} } : {} }catch (error) {
      // The default processing is loading
      checkLoading && checkLoading(false)
      // Error callback
      errorCallBack && errorCallBack()
      console.error(`error: ${error}`)
    }
  }

  init && doResult(params)

  return isLoading ? {
    loading,
    result,
    doResult
  } : {
    result,
    doResult
  }
}
Copy the code

conclusion

Thanks to previous react-hooks, I was able to write composite apis with ease