最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

使用 vueuse 的 useRouteQuery 碰到的問題

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

答:因?yàn)樵谑褂?code><KeepAlive>保活的頁面級組件之間切換時,在所有組件中使用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)變量都會更新。

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

思考:

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

1. 簡易實(shí)現(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
}

實(shí)際使用過后,我們會發(fā)現(xiàn)以上實(shí)現(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
// 實(shí)際:?title=test

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

2. 完整實(shí)現(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
}

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

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

相關(guān)文章

  • vue雙向數(shù)據(jù)綁定原理分析、vue2和vue3原理的不同點(diǎn)

    vue雙向數(shù)據(jù)綁定原理分析、vue2和vue3原理的不同點(diǎn)

    這篇文章主要介紹了vue雙向數(shù)據(jù)綁定原理分析、vue2和vue3原理的不同點(diǎn),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • vue如何跳轉(zhuǎn)到其他頁面

    vue如何跳轉(zhuǎn)到其他頁面

    跳轉(zhuǎn)到指定URL,向history棧添加一個新的紀(jì)錄,點(diǎn)擊后退會返回至上一個頁面,這篇文章給大家介紹vue如何跳轉(zhuǎn)到其他頁面,包括無參跳轉(zhuǎn)和帶參跳轉(zhuǎn),本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2023-10-10
  • vue element-ui el-date-picker限制選擇時間為當(dāng)天之前的代碼

    vue element-ui el-date-picker限制選擇時間為當(dāng)天之前的代碼

    這篇文章主要介紹了vue element-ui el-date-picker如何限制選擇時間為當(dāng)天之前,文中給大家提供了代碼段和截圖,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-11-11
  • 詳解vue 組件注冊

    詳解vue 組件注冊

    這篇文章主要介紹了vue 組件注冊的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)vue 組件的相關(guān)知識,感興趣的朋友可以了解下
    2020-11-11
  • 淺入深出Vue之組件使用

    淺入深出Vue之組件使用

    這篇文章主要給大家介紹了關(guān)于淺入深出Vue之組件使用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Vue具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • vue.js添加一些觸摸事件以及安裝fastclick的實(shí)例

    vue.js添加一些觸摸事件以及安裝fastclick的實(shí)例

    今天小編就為大家分享一篇vue.js添加一些觸摸事件以及安裝fastclick的實(shí)例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-08-08
  • Vue3.0組件通信mitt源碼ts實(shí)例解析

    Vue3.0組件通信mitt源碼ts實(shí)例解析

    這篇文章主要為大家介紹了Vue3.0組件通信mitt源碼ts實(shí)例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • 詳解用vue2.x版本+adminLTE開源框架搭建后臺應(yīng)用模版

    詳解用vue2.x版本+adminLTE開源框架搭建后臺應(yīng)用模版

    這篇文章主要介紹了用vue2.x版本+adminLTE開源框架 搭建后臺應(yīng)用模版,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-03-03
  • vue插件v-touch的坑及解決(不能上下滑動)

    vue插件v-touch的坑及解決(不能上下滑動)

    這篇文章主要介紹了vue插件v-touch的坑及解決(不能上下滑動),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Vue計算屬性實(shí)現(xiàn)成績單

    Vue計算屬性實(shí)現(xiàn)成績單

    這篇文章主要為大家詳細(xì)介紹了Vue計算屬性實(shí)現(xiàn)成績單,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08

最新評論

彭州市| 建水县| 高邑县| 巩义市| 南平市| 盐亭县| 邯郸市| 民勤县| 石嘴山市| 施甸县| 喀喇沁旗| 南和县| 宣恩县| 普格县| 栖霞市| 巫溪县| 平和县| 玉田县| 蓬安县| 如东县| 阿拉尔市| 广安市| 庐江县| 岳西县| 老河口市| 南皮县| 阳东县| 左权县| 从化市| 贵溪市| 扎囊县| 射阳县| 韶关市| 区。| 拜城县| 仁布县| 临安市| 永福县| 聂拉木县| 阜宁县| 平度市|