vue-route-query-hook:一个用于 Vue 3 的 Composable,提供响应式参数与 URL 查询参数之间的双向同步功能

vue-route-query-hook

一个用于 Vue 3 的 Composable,提供响应式参数与 URL 查询参数之间的双向同步功能。

特性

  • 🔄 双向同步: 响应式参数与 URL 查询参数自动同步
  • 🎯 类型安全: 完整的 TypeScript 支持
  • ⚙️ 灵活配置: 支持排除字段、空值处理等多种配置
  • 🚀 Vue 3: 基于 Vue 3 Composition API
  • 📦 轻量级: 无额外依赖,仅依赖 Vue 和 Vue Router

安装

bash 复制代码
npm install vue-route-query-hook

或使用 yarn:

bash 复制代码
yarn add vue-route-query-hook

或使用 pnpm:

bash 复制代码
pnpm add vue-route-query-hook

基础用法

vue 复制代码
<template>
  <div>
    <input v-model="searchParams.keyword" placeholder="搜索关键词" />
    <select v-model="searchParams.status">
      <option value="">全部</option>
      <option value="active">激活</option>
      <option value="inactive">未激活</option>
    </select>
    <input v-model.number="searchParams.page" type="number" min="1" />

    <button @click="resetParams()">重置</button>
  </div>
</template>

<script setup lang="ts">
import { reactive, toRef } from "vue";
import { useRouteQuery } from "vue-route-query-hook";

const searchParams = reactive({
  keyword: "",
  status: "",
  page: 1,
});

const { updateRouteQuery, resetParams } = useRouteQuery({
  q: toRef(searchParams, "keyword"),
  status: toRef(searchParams, "status"),
  page: toRef(searchParams, "page"),
});
</script>

API

useRouteQuery(params, options?)

参数
  • params : QueryParams - 要同步的响应式参数对象

    • key: 路由参数名
    • value: Vue 响应式引用 (Ref)
  • options : UseRouteQueryOptions (可选) - 配置选项

返回值

返回一个包含以下方法的对象:

  • updateRouteQuery : () => void - 手动更新路由查询参数
  • initParamsFromRoute : () => void - 从路由初始化参数
  • resetParams : (resetValues?) => void - 重置参数为初始值

配置选项

UseRouteQueryOptions

typescript 复制代码
interface UseRouteQueryOptions {
  /**
   * 排除的字段,这些字段不会同步到路由
   * @default []
   */
  excludeKeys?: string[];

  /**
   * 是否立即执行 watch 监听
   * @default true
   */
  immediate?: boolean;

  /**
   * 是否在组件挂载时从路由初始化参数
   * @default true
   */
  initFromRoute?: boolean;

  /**
   * 空值处理方式
   * - 'remove': 移除参数
   * - 'keep': 保留参数
   * @default 'remove'
   */
  emptyValueHandle?: "remove" | "keep";
}

高级用法

排除某些字段

typescript 复制代码
const searchParams = reactive({
  keyword: "",
  internalFlag: false, // 这个字段不需要同步到 URL
});

useRouteQuery(
  {
    q: toRef(searchParams, "keyword"),
    internal: toRef(searchParams, "internalFlag"),
  },
  {
    excludeKeys: ["internal"], // 排除 internal 字段
  }
);

手动控制同步时机

typescript 复制代码
const { updateRouteQuery } = useRouteQuery(
  {
    status: toRef(searchParams, "status"),
  },
  {
    immediate: false, // 禁用自动同步
  }
);

// 在需要的时候手动同步
function handleSubmit() {
  updateRouteQuery();
}

保留空值参数

typescript 复制代码
useRouteQuery(
  {
    q: toRef(searchParams, "keyword"),
  },
  {
    emptyValueHandle: "keep", // 空值时保留参数为空字符串
  }
);

自定义重置值

typescript 复制代码
const { resetParams } = useRouteQuery({
  keyword: toRef(searchParams, "keyword"),
  page: toRef(searchParams, "page"),
});

// 重置为默认值
resetParams();

// 重置为指定值
resetParams({
  keyword: "default search",
  page: 1,
});

类型支持

该包提供完整的 TypeScript 类型支持:

typescript 复制代码
import type {
  QueryValue,
  QueryParams,
  UseRouteQueryOptions,
  UseRouteQueryReturn,
} from "vue-route-query-hook";

类型定义

typescript 复制代码
type QueryValue = string | number | boolean | undefined | null;
type QueryParams = Record<string, Ref<QueryValue>>;

注意事项

  1. 类型转换: Hook 会根据原始值的类型自动转换路由参数

    • number: 转换为数字,无效时保持原值
    • boolean: 'true' 转换为 true,其他为 false
    • string: 直接返回字符串值
  2. 历史记录 : 使用 router.replace 更新路由,不会产生浏览器历史记录

  3. 深度监听: 自动开启深度监听,支持嵌套对象的变化检测

兼容性

  • Vue 3.0+
  • Vue Router 4.0+

仓库地址

许可证

MIT

作者

高顺鹏 handsome@gaoshunpeng.cn

相关推荐
徐小夕37 分钟前
jitword 协同文档3.2发布:打造浏览器中最强word编辑器
前端·架构·github
纯爱掌门人2 小时前
干了这么多年前端,聊聊 2026 年我们到底还值不值钱
前端·程序员
houhou2 小时前
Monaco Editor 集成指南:从配置到优化
前端
hunterandroid2 小时前
[Android 从零到一] Custom View 自定义绘制:从 onDraw 到完整交互
前端
李明卫杭州2 小时前
Vue3 v-memo 指令详解:让你的列表渲染性能翻倍 🚀
前端
梨子同志2 小时前
Monorepo
前端
lihaozecq2 小时前
继 Web Coding Agent 后,我做了一个本地优先的桌面 AI Agent
前端·agent
用户298698530143 小时前
在 React 中使用 JavaScript 将 Excel 转换为 SVG
前端·javascript·react.js
CodingSpace3 小时前
ESLint
前端
Csvn3 小时前
异步错误捕获的六大陷阱:await 裹着 try-catch 就一定稳了吗?
前端