欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

vue3結(jié)合ts從零實現(xiàn)vueuse的useRouteQuery方法

 更新時間:2024年03月28日 11:29:21   作者:求知若饑  
這篇文章主要為大家詳細介紹了如何使用vue3與ts從零實現(xiàn)一個類vueuse的useRouteQuery方法,并解決vueuse的useRouteQuery方法存在的一些問題,感興趣的可以了解下

本文將使用vue3ts從零實現(xiàn)一個類vueuseuseRouteQuery方法,接受基本相同的參數(shù)(移除了router與route參數(shù)),并解決vueuseuseRouteQuery方法存在的一些問題。

使用 vueuse 的 useRouteQuery 碰到的問題

問:為什么不使用vueuse的提供的useRouteQuery方法?

答:因為在使用<KeepAlive>?;畹捻撁婕壗M件之間切換時,在所有組件中使用vueuseuseRouteQuery方法定義的變量都會更新。

例如:打開A頁面(?;?后,修改page為2,假設(shè)url現(xiàn)在為/pageA?page=2,然后切換到B頁面,A頁面將會觸發(fā)watchpage將會更新為默認(rèn)值,并且每次修改B頁面的query都會觸發(fā)A頁面的query更新。代碼如下。

import { useRouteQuery } from '@vueuse/router'
import { watch } from 'vue'

// 頁面A (KeepAlive)
const page = useRouteQuery('page', 1, { transform: Number })
watch(page, (value) => {
    console.log('page A', value)
})

// 頁面B  (KeepAlive)
const pageSize = useRouteQuery('pagesize', 10, { transform: Number })
watch(pageSize, (value) => {
    console.log('page B', value)
})

查看vueuseuseRouteQuery的源碼后發(fā)現(xiàn)它是根據(jù)router對象去保存query信息的,因此每次urlquery變化時,所有已存在的相關(guān)變量都會更新。

從零實現(xiàn)一個 useRouteQuery

思考:

  • 監(jiān)聽route.query的變化,在值變化時更新響應(yīng)式變量的值;
  • 監(jiān)聽響應(yīng)式變量的變化,在值變化時修改route.query的值;
  • route.query變化時,判斷是否是當(dāng)前頁面,不是則跳過更新過程。

1. 簡易實現(xiàn)

import { watch, ref, type Ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'

type IQuery = string | number | string[] | null | undefined

/**
 * 獲取當(dāng)前頁面的query
 * @param name
 * @param defaultValue
 * @param options
 * @returns
 */
export const useRouteQuery = <T extends IQuery, K extends IQuery = T>(
  name: string,
  defaultValue?: T,
  options: {
    transform?: (value: any) => K
    mode?: 'push' | 'replace'
    isEncodeURIComponent?: boolean
  } = {}
) => {
  const { mode = 'push', transform = (value) => value, isEncodeURIComponent = false } = options

  const route = useRoute()
  const router = useRouter()
  const currentPath = route.path
  const query = ref(defaultValue) as Ref<T | K>

  watch(
  () => route.query[name],
    (value) => {
      // 不是當(dāng)前頁面時不更新
      if (route.path !== currentPath) {
        return
      }
      if (value === undefined) {
        query.value = defaultValue as T
        return
      }
      if (!isEncodeURIComponent) {
        query.value = transform(value)
        return
      }
      query.value = transform(decodeURIComponent(value as string))
    },
    { immediate: true })

  watch(query, (value) => {
    const { params, query: oldQuery, hash } = route
    router[mode]({
      params,
      query: {
        ...oldQuery,
        [name]: isEncodeURIComponent ? encodeURIComponent(value as string) : value
      },
      hash
    })
  })

  return query
}

實際使用過后,我們會發(fā)現(xiàn)以上實現(xiàn)存在一些問題:

多個變量同步修改時,route.query上只會保留最后一個修改的響應(yīng)式變量,代碼如下;

import { useRouteQuery } from '@/hooks/useRouteQuery'

const disabled = useRouteQuery('disabled', 0)
const title = useRouteQuery('title', '')

disabled.value = 1
title.value = 'test'
// 預(yù)想:?disabled=1&title=test
// 實際:?title=test

特殊值undefined、null經(jīng)過encodeURIComponent處理后會轉(zhuǎn)換為字符串格式,因此還會帶在route.query上,如“?diabled=null&title=undefined”。

2. 完整實現(xiàn)

解決方案:

  • 通過在函數(shù)外定義一個隊列來保存所有需要更新的值,并異步更新route.query;
  • 特殊值不使用encodeURIComponent方法轉(zhuǎn)義。
import { nextTick, watch, ref, type Ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'

type IQuery = string | number | string[] | null | undefined
// 用來保存所有的query
const queriesQueue = new Map<string, Record<string, IQuery>>()
/**
 * 獲取當(dāng)前頁面的query
 * @param name
 * @param defaultValue
 * @param options
 * @returns
 */
export const useRouteQuery = <T extends IQuery, K extends IQuery = T>(
  name: string,
  defaultValue?: T,
  options: {
    transform?: (value: any) => K
    mode?: 'push' | 'replace'
    isEncodeURIComponent?: boolean
  } = {}
) => {
  const { mode = 'push', transform = (value) => value, isEncodeURIComponent = false } = options

  const route = useRoute()
  const router = useRouter()
  const currentPath = route.path
  const query = ref(defaultValue) as Ref<T | K>

  watch(
    () => route.query[name],
    (value) => {
      if (route.path !== currentPath) {
        return
      }
      if (value === undefined) {
        query.value = defaultValue as T
        return
      }
      if (!isEncodeURIComponent) {
        query.value = transform(value)
        return
      }
      query.value = transform(decodeURIComponent(value as string))
    },
    { immediate: true })

  const setQueryQueue = (value: IQuery) => {
    const currentPageQueries = queriesQueue.get(currentPath) || {}
    // 特殊值不轉(zhuǎn)義
    if (value === null || value === undefined) {
      currentPageQueries[name] = value
    } else {
      currentPageQueries[name] = isEncodeURIComponent ? encodeURIComponent(value as string) : value
    }

    queriesQueue.set(currentPath, currentPageQueries)
  }

  watch(query, (value) => {
    setQueryQueue(value as IQuery)
    // 異步更新
    nextTick(() => {
      // 獲取當(dāng)前頁面所有的query
      const currentPageQueries = queriesQueue.get(currentPath) || {}
      const { params, query: oldQuery, hash } = route
      router[mode]({
        params,
        query: {
          ...oldQuery,
          ...currentPageQueries
        },
        hash
      })
    })
  })

  return query
}

查看完整實現(xiàn)源碼。

到此這篇關(guān)于vue3結(jié)合ts從零實現(xiàn)vueuse的useRouteQuery方法的文章就介紹到這了,更多相關(guān)vue實現(xiàn)vueuse的useRouteQuery內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 淺談vue的props,data,computed變化對組件更新的影響

    淺談vue的props,data,computed變化對組件更新的影響

    本篇文章主要介紹了淺談vue的props,data,computed變化對組件更新的影響,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • 詳解vue父子組件間傳值(props)

    詳解vue父子組件間傳值(props)

    本篇文章主要介紹了詳解vue父子組件間傳值(props),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06
  • vue3新擬態(tài)組件庫開發(fā)流程之table組件源碼分析

    vue3新擬態(tài)組件庫開發(fā)流程之table組件源碼分析

    這篇文章主要介紹了vue3新擬態(tài)組件庫開發(fā)流程——table組件源碼,本文通過示例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-04-04
  • 深入理解Vue生命周期、手動掛載及掛載子組件

    深入理解Vue生命周期、手動掛載及掛載子組件

    本篇文章主要介紹了深入理解Vue生命周期和手動掛載,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • vue實現(xiàn)購物車拋物線小球動畫效果的方法詳解

    vue實現(xiàn)購物車拋物線小球動畫效果的方法詳解

    這篇文章主要介紹了vue實現(xiàn)購物車拋物線小球動畫效果的方法,結(jié)合實例形式較為詳細的分析了vue.js實現(xiàn)拋物線動畫效果購物車功能相關(guān)原理與操作注意事項,需要的朋友可以參考下
    2019-02-02
  • avue-crud多級復(fù)雜的動態(tài)表頭的實現(xiàn)示例

    avue-crud多級復(fù)雜的動態(tài)表頭的實現(xiàn)示例

    Avue.js?是基于現(xiàn)有的element-ui庫進行的二次封裝,本文主要介紹了avue-crud多級復(fù)雜的動態(tài)表頭,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • vue.js實現(xiàn)格式化時間并每秒更新顯示功能示例

    vue.js實現(xiàn)格式化時間并每秒更新顯示功能示例

    這篇文章主要介紹了vue.js實現(xiàn)格式化時間并每秒更新顯示功能,結(jié)合實例形式分析了vue.js時間格式化顯示與基于定時器進行實時更新的相關(guān)操作技巧,需要的朋友可以參考下
    2018-07-07
  • vue+openlayers+nodejs+postgis實現(xiàn)軌跡運動效果

    vue+openlayers+nodejs+postgis實現(xiàn)軌跡運動效果

    使用postgres(postgis)數(shù)據(jù)庫以及nodejs作為后臺,vue和openlayers做前端,openlayers使用http請求通過nodejs從postgres數(shù)據(jù)庫獲取數(shù)據(jù),這篇文章主要介紹了vue+openlayers+nodejs+postgis實現(xiàn)軌跡運動,需要的朋友可以參考下
    2024-05-05
  • vue中用qrcode庫將超鏈接生成二維碼圖片的示例代碼

    vue中用qrcode庫將超鏈接生成二維碼圖片的示例代碼

    生成二維碼是一種常見的需求,無論是用于商業(yè)宣傳還是個人分享,二維碼都可以提供快速方便的方式來傳遞信息,在Vue框架中,我們可以使用qrcode庫來輕松地生成二維碼,本篇博文將介紹如何安裝qrcode庫,并通過一個實際例子來展示如何生成二維碼,需要的朋友可以參考下
    2023-12-12
  • Vue中的directive指令快速使用

    Vue中的directive指令快速使用

    這篇文章主要介紹了Vue中的directive指令快速使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10

最新評論