今天介绍的工具库是 qs。它支持嵌套对象向 search-string 的序列化及反序列化。
背景
什么是 search-string? 简单来说地址栏 ? 及后面的参数就是 search-string。
var url = new URL('https://developer.mozilla.org/en-US/docs/Web/API/URL/search?q=123');
var queryString = url.search; // "?q=123"
一般来说 search-string 使用的是 URL encode,如果你使用过 URLSearchParams,它支持将简单的扁平化对象序列化成 search-string。
var paramsString = "q=URLUtils.searchParams&topic=api"
var searchParams = new URLSearchParams(paramsString);
for (let p of searchParams) {
console.log(p);
}
searchParams.has("topic") === true; // true
searchParams.get("topic") === "api"; // true
searchParams.getAll("topic"); // ["api"]
searchParams.get("foo") === null; // true
searchParams.append("topic", "webdev");
searchParams.toString(); // "q=URLUtils.searchParams&topic=api&topic=webdev"
searchParams.set("topic", "More webdev");
searchParams.toString(); // "q=URLUtils.searchParams&topic=More+webdev"
searchParams.delete("topic");
searchParams.toString(); // "q=URLUtils.searchParams"
上面是 MDN 的官方示例,可以看到 URLSearchParams 支持解析生成一个封装对象用于操作、查询 search-string。不过,可以看到这种操作方式十分繁琐,直观下我们更希望直接解析得到一个 Plain Object,使用 searchParams.foo 而不是 searchParams.get('foo') 。
使用 qs
今天我们的主角qs就很好地解决了这个问题。
import qs from "qs";
var paramsString = "q=URLUtils.searchParams&topic=api";
var query = qs.parse(paramsString);
console.log(query); // {q: "URLUtils.searchParams", topic: "api"}
console.log(qs.stringify(query)); // q=URLUtils.searchParams&topic=api
qs.parse 直接生成了一个 Plain Object,而 qs.stringify 也直接使用 Plain Object 转化成 query-string。
再一大亮点就是 qs 支持嵌套对象的解析。
import qs from "qs";
const obj = { a: "1", b: { c: "2" }, c: [1, 2, 3] };
console.log(new URLSearchParams(obj).toString());
// a=1&b=%5Bobject+Object%5D&c=1%2C2%2C3
const objString = qs.stringify(obj, { allowDots: true });
console.log(objString);
// a=1&b.c=2&c%5B0%5D=1&c%5B1%5D=2&c%5B2%5D=3
console.log(qs.parse(objString, { allowDots: true }));
// { a: "1", b: { c: "2" }, c: [1, 2, 3] }
可以看到 URLSearchParams 并不直接支持嵌套对象的序列化,产生了错误的结果,而 qs.stringify 正常生成了 query string,但是这里要注意使用了 allowDots 不转译 . 号,那么使用 qs.parse 的使用也需要加上 allowDots 来正常解析字符串。
场景
前端应用不断丰富、完善的今天,页面之间的跳转、衔接是必需的。在跳转路由的时候,我们就需要为即将进入的页面提供一些关键信息,比如某个实体的 id 、表格的查询条件、页码等。使用 search string 也就非常普遍。
根据使用的场景,建议只在跳转之后的第一次渲染获取 search string 的内容并解析出参数对象来初始化页面中的组件,在状态更新的时候使用 history.replace (react-router)更新路由中的 search 参数,通过设定页面中的关键参数,便于用户对链接进行分享时能够正常打开并还原页面状态。