这篇文章主要讲解了“vue如何实现前端保持筛选条件到url并进行同步参数设计”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“vue如何实现前端保持筛选条件到url并进行同步参数设计”吧!
假设 url 上的参数为 ?a=1&a=2&b=true
,来看看获取参数的方法
const searchParams = new URLSearchParams(window.location.search);
// ["1", "2"]
searchParams.getAll("a");
// "1"
searchParams.get(a);
// ["true"]
searchParams.getAll(b);
// "true"
searchParams.get(b);
添加
searchParams.append("a", "1");
searchParams.append("a", "2");
// ?a=1&a=2
searchParams.set("b", "3");
searchParams.set("b", "4");
// ?b=4
从上面的结果可以得知,无论什么值最后都会被解析成 string
类型, 如果存在两个名字相同的 key,则会被解析为 string[]
。 所以从 url 参数获取到的类型只会为 string | string[]
。
最后使用 history.pushState 来修改浏览器地址栏的 url 参数。与 history.replaceState 不同的是,一个是添加一条新记录,一个是替换。在这里我们当然是选择添加新记录了。
首先肯定要知道哪些值需要同步到 url 参数上,所以我们定义了一个 configs
参数,来配置需要同步的值。类型为数组,这样可以让用户自定义顺序,每项需要传入一个 key 值。
hook 内部返回一个 syncToUrl
方法,传入包含配置的所有 key 的值。用户可以在自己需要的时候同步 url。
const { syncToUrl } = useSyncUrl({
configs: [{ key: "title" }, { key: "status" }]
})
// 同步
syncToUrl(values)
假设 title
与输入框绑定,且没有值,传入 syncToUrl
的是 ""
,这就没有必要同步到 url 上了。所以我们添加一个配置 omitEmptyString
,如果值为空字符串,则忽略。
[{ key: "title", omitEmptyString: true }]
同理,可以增加 omitNull
、omitUndefined
。这三个默认都设为 true
。
接下来,我们先明白两个概念。在页面第一次加载、执行浏览器前进回退操作时,需要将 url 参数的值转换到当前页面的组件中,在这里我们称其为 decode
。
在页面中筛选结束点击提交或切换页码时,需要将这些值转换成参数并设置到 url 的参数上,在这里我们称其为 encode
。
了解后,我们就可以知道上面例子中 key: "status"
,可以想成是一个 Select
组件,值为 boolean
类型。从基础知识可以得知,从 url 取下来的值为 string
类型。 需要使用 decode
转换成 boolean
类型。
const values = reactive({ title: "", status: false });
const booleanValues = {
true: true,
false: false,
}
const { syncToUrl } = useSyncUrl({
configs: [
{
// title 的值是字符串类型,所以不需要 decode
key: "title",
},
{
key: "status",
// 参数是从 url 上 key 为 status 的值
decode: (value) => booleanValues[value]
}
],
onDecode: (params) => {
Object.keys(params).forEach(key => {
values[key] = params[key]
});
// 设置完成后,在这里请求数据
}
})
在 decode
中,我们将值 return 出去,在 onDecode
中将每个配置项返回的值统一收集起来,设置完成后,请求列表数据。像 title
这种值本身是字符串的就不用写 decode
。假设 url 上的参数为 ?title=11&status=true
,这里的 params
的值就为
{
title: "11",
status: true
}
decode
也可以返回一个对象,如果是对象也会被收集到 onDecode
中。如果不想被收集,可以返回空对象 {}
。所以如果你想在 decode
中进行赋值也可以,但要返回 {}
。
decode: (value) => {
return {
a: "1",
b: "2"
}
}
// 不会被收集
decode: (value) => {
return {};
}
const values = reactive({ rangeDate: ["2022-10-1", "2022-10-2"] });
useSyncUrl({
configs: [
{
key: "rangeDate",
encode: (value) => {
return {
starDate: value[0],
endDate: value[1]
}
}
}
]
})
encode
可以将值转换成你想要的格式同步到 url 上。这个例子中如果不写 encode
,通过了解上面的基础知识,则会被转换成两个 rangeDate 的键值对。这里自定义转换成了 starDate 和 endDate。所以还要配合 decode
使用。
decode: (value) => ...
但是这个 value 返回的是 url 上 key 为 "rangeDate" 的值,我们要怎么 decode
starDate 和 endDate 呢?所以增加一个配置项 decodeKeys
来实现。。
{
key: "rangeDate",
decodeKeys: ["starDate", "endDate"],
decode: value => {
return {
rangeDate: [value.starDate, value.endDate]
}
}
}
通过上面基础知识可以得知,url 的值只能为 string | string[]
,所以 encode
返回的值也只能是 EncodeResult | Record<string, EncodeResult>
。内部将 number
和 boolean
转换成了 string
。
type EncodeResult = string | number | boolean | (string | number | boolean)[];
这时候就有问题了,我想将一个比较复杂类型的值同步到 url 上怎么办?这时候就要用到 encodeURIComponent
和 decodeURIComponent
了,如果你不认识,可以上 MDN 学习。这里判定数据一定为正确的,实际使用中在 decode
这步中 JSON.parse 可能会报错,你需要自行处理一下,因为 url 可能会被人为修改。
const values = reactive({
obj: { a: { b: { c: true } } },
});
const { syncToUrl } = useSyncUrl({
configs: [
{
key: "obj",
encode: (value) => encodeURIComponent(JSON.stringify(value)),
decode: (value) => JSON.parse(decodeURIComponent(value)),
},
],
});
假如你的详情页有一个按钮点击返回列表页,要怎么保留上次的筛选条件呢?因为 vue-router
的 push 操作,不能直接传 url 参数的字符串,只能传对象,所以返回一个参数对象。
localStorage.setItem("listSearch", window.location.search);
// 在详情页
router.push(`/list${localStorage.getItem("listSearch")}`)
或
const { searchParams } = useSyncUrl(...)
localStorage.setItem("listSearch", JSON.stringify(searchParams))
// 在详情页
router.push({ path: "/list", query: JSON.parse(localStorage.getItem("listSearch")) })
感谢各位的阅读,以上就是“vue如何实现前端保持筛选条件到url并进行同步参数设计”的内容了,经过本文的学习后,相信大家对vue如何实现前端保持筛选条件到url并进行同步参数设计这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。