TanStack Router 如何自定义搜索参数的 JSON 序列化规则
TanStack Router 如何自定义搜索参数的 JSON 序列化规则【免费下载链接】router A client-first, server-capable, fully type-safe router and full-stack framework for the web (React and more).项目地址: https://gitcode.com/GitHub_Trending/ro/routerTanStack Router 默认用JSON.stringify和JSON.parse自动解析和序列化 URL 搜索参数同时做 escape/unescape。如果你的搜索对象包含嵌套结构或者默认的 JSON 格式不满足需求——比如想要 Base64 编码以获得更好的浏览器和 URL 预览展开器兼容性或者想换成query-string这类专门的序列化库——可以通过createRouter的parseSearch和stringifySearch两个选项替换整个序列化/反序列化流程。先看默认行为是什么样的使用默认配置时下面的搜索对象const search { page: 1, sort: asc, filters: { author: tanner, min_words: 800 }, }会被序列化并转义为这样的搜索字符串?page1sortascfilters%7B%22author%22%3A%22tanner%22%2C%22min_words%22%3A800%7D也就是说一级参数保持扁平、基于字符串非字符串值数字、布尔会被保留为实际类型嵌套对象会被 JSON 序列化后再 URL 转义。这个默认行为等价于显式写入import { createRouter, parseSearchWith, stringifySearchWith, } from tanstack/react-router const router createRouter({ // ... parseSearch: parseSearchWith(JSON.parse), stringifySearch: stringifySearchWith(JSON.stringify), })Solid 项目中把导入来源换成tanstack/solid-router其余写法相同。配置入口parseSearch 与 stringifySearch 选项这两个选项都在 Router 配置中类型与默认值见 RouterOptionsstringifySearch类型(search: Recordstring, any) string可选默认defaultStringifySearch。在生成链接时被用来序列化搜索参数。parseSearch类型(search: string) Recordstring, any可选默认defaultParseSearch。在解析当前 location 时被用来反序列化搜索参数。自定义时不需要手写完整的序列化流程官方提供了两个内置辅助函数parseSearchWith和stringifySearchWith你只需要传入真正负责字符串 ⇆ 对象转换的函数辅助函数会处理其余部分。一个关键约束序列化与反序列化必须是幂等的——反序列化后要能拿回同一个对象。如果你选用的库不支持嵌套对象反序列化时嵌套对象会丢失这在文档中被明确标注为需要注意的风险。示例一用 Base64 编码搜索参数Base64 编码常用于让搜索参数在浏览器和 URL unfurler 中保持最大兼容性。写法如下React 示例import { Router, parseSearchWith, stringifySearchWith, } from tanstack/react-router const router createRouter({ parseSearch: parseSearchWith((value) JSON.parse(decodeFromBinary(value))), stringifySearch: stringifySearchWith((value) encodeToBinary(JSON.stringify(value)), ), }) function decodeFromBinary(str: string): string { return decodeURIComponent( Array.prototype.map .call(atob(str), function (c) { return % (00 c.charCodeAt(0).toString(16)).slice(-2) }) .join(), ) } function encodeToBinary(str: string): string { return btoa( encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) { return String.fromCharCode(parseInt(p1, 16)) }), ) }同样配置下前面那个搜索对象会变成文档示例输出?page1sortascfilterseyJhdXRob3IiOiJ0YW5uZXIiLCJtaW5fd29yZHMiOjgwMH0%3D两点必须留意不要用裸的atob/btoa处理非 UTF-8 字符。浏览器中atob和btoa对非 UTF-8 字符没有保证能正确工作。文档建议统一使用上面这两个encodeToBinary/decodeFromBinary工具函数源码见 custom-search-param-serialization.md 的 Safe Binary Encoding/Decoding 一节而不是示例里内联的版本之外自行简化。直接 Base64 序列化用户输入有碰撞风险。如果序列化与 URL 自身的反序列化规则发生碰撞可能导致 URL 没有被正确解析、或值被解释成别的内容。避免方式就是使用上面这种安全的二进制编解码方法。示例二用 query-string 库可选分支query-string是另一种常见选择。配置方式是把库的stringify/parse包进辅助函数import { createRouter } from tanstack/react-router import qs from query-string const router createRouter({ // ... stringifySearch: stringifySearchWith((value) qs.stringify(value, { // ...options }), ), parseSearch: parseSearchWith((value) qs.parse(value, { // ...options }), ), })这里的// ...options是query-string自身的选项由你按库文档自行决定。该配置下前面那个搜索对象会变成文档示例输出?page1sortascfiltersauthor%3Dtanner%26min_words%3D800文档还给出了另外两个同模式的示例JSURL2parseSearchWith(parse)/stringifySearchWith(stringify)直接传入库函数示例输出为?page1sortascfilters(author~tanner~min*_words~800)~和 ZipsonJSON 压缩库需要叠加 base64 编解码即复用encodeToBinary/decodeFromBinary。两者的完整代码都在 custom-search-param-serialization.md 中替换方式和上面完全一致不再展开。如何验证配置生效验证方式分两步都基于文档已给出的行为看 URL配置生效后通过Link search{{...}}或navigate生成的链接其查询字符串应该呈现你所选格式的形态如 Base64 的eyJ...或 query-string 的filtersauthor%3Dtanner%26min_words%3D800。文档中给出的各格式查询串都可以作为对照样本。看反序列化结果在路由组件里用useSearch读回搜索参数确认嵌套结构被完整还原参见 search-params.mdconst { page, sort, filters } Route.useSearch() // filters 应为 { author: tanner, min_words: 800 }判断标准就是幂等性从 URL 解析回来必须得到与写入时相同的对象。如果某个字段尤其是嵌套对象在useSearch里丢失或变成字符串说明所选的序列化/反序列化函数对这种数据结构不对称需要换库或换回 JSON 默认行为。限制与注意事项两个选项的类型签名决定了自定义函数只处理搜索对象 ⇆ 查询字符串这一段location 解析和链接生成由 Router 调用这两个函数完成。文档明确警告了 Base64 直接编码用户输入可能产生的 URL 解析碰撞以及不支持嵌套对象的库会静默丢失嵌套数据这两类失败模式——选择自定义方案前先确认所选库对嵌套对象的支持。完整的默认行为JSON-first 解析、一级参数扁平、数字/布尔类型保留说明见 search-params.md自定义序列化的完整代码与 Safe Binary Encoding/Decoding 工具函数见 custom-search-param-serialization.md。【免费下载链接】router A client-first, server-capable, fully type-safe router and full-stack framework for the web (React and more).项目地址: https://gitcode.com/GitHub_Trending/ro/router创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考