stao-ui

website·Indexed 29 days ago

https://wansongtao.github.io/stao-ui/

A collection of commonly used Vue 2/3 components, JavaScript/TypeScript utility methods, CSS, and general tool encapsulations. It includes base components like Button, Radio, Checkbox, and Slider, as well as specialized utilities such as Axios plugins for request retries and deduplication, hooks like useRequest and useURLQuery, and libraries for ExcelJS and Chinese number conversion.

Tokens
18.2K
Snippets
106
Records
127
Agent score
75%

What's inside stao-ui

  1. Overview of web-storage-plus features

    web-storage-plus enhances the standard localStorage and sessionStorage APIs with the following capabilities:

    • Expiration time settings and namespaces.
    • Support for both synchronous and asynchronous operations.
    • Custom JSON stringification and parsing functions.
    • Encryption and decryption function support.
    • Enhanced stringify/parse methods that support types not handled by standard JSON, including function, regexp, date, undefined, NaN, Infinity, -Infinity, and bigint.
    • encode/decode functions for Base64 conversion of strings.
  2. Use FileSelector for file and folder selection

    The FileSelector component provides a customizable interface for selecting files or directories. It handles the hidden HTML file input and provides a trigger element (via slot or default button) to open the file dialog. It supports constraints on file types, quantity, and size.
    <template>
      <!-- Default usage -->
      <FileSelector />
    
      <!-- Custom trigger button and image restriction -->
      <FileSelector accept="image/*">
        <div class="upload">Select Images</div>
      </FileSelector>
    </template>
    
    <script setup>
    import FileSelector from '@/FileSelector/FileSelector.vue';
    </script>
  3. stao-ui usage recommendations and limitations

    Because the library is under active development and moving toward a headless style, it is recommended to copy the source code of components or functions directly into your project. This ensures stability and allows for easier customization. Note that tree-shaking/on-demand imports (按需引入) are currently not supported.
  4. Manage paginated requests with useRequest

    The useRequest hook is used to handle paginated API requests. It manages the request lifecycle, including sending the request, tracking loading states, and storing the resulting data and total count. It can be configured to automatically trigger requests when pagination parameters change.
  5. Detect clicks outside an element using v-click-outside

    v-click-outside is a Vue directive used to trigger a callback function when a user clicks outside the element the directive is attached to. It works by adding a click event listener to the document body and checking if the click target is contained within the element.
  6. Implement automatic request retries with AxiosRetryPlugin

    The axios-retry plugin provides a mechanism to automatically retry failed Axios requests. It works by integrating with Axios response interceptors to detect failures and re-trigger the request based on a specified retry count and delay. It uniquely identifies requests using a generated key based on the method, URL, data, and params to track retry counts per unique request.
  7. Install and initialize VueAMap in a Vue application

    To use the VueAMap map components, you must install the @vuemap/vue-amap package, import its styles, and initialize the AMap API loader with a valid key and security code from the Gaode Maps Developer Platform.
    import VueAMap, { initAMapApiLoader } from '@vuemap/vue-amap'
    import '@vuemap/vue-amap/dist/style.css'
    
    // Initialize with keys from Gaode Maps Developer Platform
    initAMapApiLoader({
      key: 'YOUR_AMAP_KEY',
      securityJsCode: 'YOUR_SECURITY_JS_CODE'
    })
    
    const app = createApp(App)
    app.use(VueAMap)
  8. Manage complex objects in URL queries with useURLQueryObject

    The useURLQueryObject hook is a wrapper around useURLQuery that allows storing JSON objects in a single URL query parameter. It automatically handles JSON.stringify when setting the value and JSON.parse when retrieving it. If parsing fails or the value is undefined, it reverts to the provided defaultValue.
    // Example usage of useURLQueryObject
    const searchParams = useURLQueryObject('search', { query: '', page: 1 });
    
    // Updating searchParams.value will stringify the object into the URL query 'search'
    searchParams.value = { query: 'vue', page: 2 };
  9. Render and submit Alipay payment forms using AliPayForm

    The AliPayForm component is used to handle Alipay payment form strings. It renders the provided HTML form, automatically submits it to a hidden iframe, and displays the payment QR code. It emits a handleLoaded event once the iframe has finished loading.
    <template>
      <ali-pay-form formHtml="<form>...</form>" @handle-loaded="onLoaded" />
    </template>
    
    <script setup>
    import AliPayForm from '...';
    
    const onLoaded = (loaded) => {
      console.log('Alipay QR code loaded:', loaded);
    };
    </script>
  10. Synchronize component state with URL query parameters using useURLQuery

    The useURLQuery hook allows you to get and set URL query parameters reactively. When the returned ref changes, the URL query parameter is automatically updated. Conversely, when the URL query parameter changes, the ref is updated. Unlike vueuse's useRouteQuery, useURLQuery only updates variables within the current page component, avoiding global updates across the SPA when queries change.

    It accepts three arguments:

    1. name (string): The name of the query parameter.
    2. defaultValue (optional): The value to use if the parameter is missing from the URL.
    3. options (optional object):
      • transform: A function to convert the query value type.
      • mode: Either 'push' or 'replace' to determine how the router updates the history.
      • isEncodeURIComponent: Boolean indicating whether to encode/decode the query parameter.
    <template>
      <input v-model="name" />
    </template>
    
    <script setup>
    import { useURLQuery } from 'useURLQuery.ts'
    
    // Gets query parameter 'name', defaults to 'default'
    // Updates URL automatically: http://localhost:8080/?name=xxx
    const name = useURLQuery('name', 'default')
    </script>
  11. Integrate Axios Deduplicator plugin into axios

    The Axios Deduplicator plugin prevents duplicate requests by integrating into axios interceptors. It tracks active requests and ensures that subsequent identical requests wait for the first one to resolve rather than triggering new network calls.
    import axios from 'axios'
    import createAxiosDeduplicatorPlugin from '...'
    
    const instance = axios.create()
    
    const deduplicator = createAxiosDeduplicatorPlugin()
    
    // Register request interceptor
    instance.interceptors.request.use(deduplicator.requestInterceptor)
    
    // Register response interceptors (fulfilled and rejected)
    instance.interceptors.response.use(
      deduplicator.responseInterceptorFulfilled,
      deduplicator.responseInterceptorRejected
    )
  12. Implement automatic token refresh in Axios

    Use the createRefreshTokenPlugin utility to automatically refresh authentication tokens when a request fails (e.g., 401 Unauthorized). The plugin handles the refresh logic and automatically retries pending requests once the new token is acquired, ensuring a seamless user experience.
    import axios from 'axios'
    import createRefreshTokenPlugin from './path-to-plugin'
    
    const instance = axios.create()
    
    const twinTokenPlugin = createRefreshTokenPlugin(
      async () => {
        // 1. Get refresh token
        const token = getRefreshToken()
        if (!token) return false
    
        // 2. Call refresh API
        const [, res] = await refreshToken(token)
        if (!res) return false
    
        // 3. Save new tokens
        saveToken(res.data.token, res.data.refreshToken)
        return true
      },
      instance.request
    )
    
    // Register interceptors
    instance.interceptors.request.use(twinTokenPlugin.requestInterceptor)
    instance.interceptors.response.use(undefined, twinTokenPlugin.responseInterceptorRejected)