vue实现前端保持筛选条件到url并进行同步参数设计

目录
  • 前言
  • 基础知识
  • 设计思路
    • decode
    • encode
    • 详情页返回列表页
  • 结语

前言

在有列表页的系统中,常常为了提高用户体验,需要保持列表页的筛选条件、分页情况。需要做到刷新页面,从详情页返回列表页保留之前的筛选情况。你可能会说 vue 用 keep-alive 缓存列表页不就行了?为什么不好呢?

因为正确的做法是将筛选条件保存在 url 上,这样可以复制给别人直接使用,并且你可以看到几乎所有网站都是使用这种方法。接下来会带大家了解有关 url 参数的基础知识和设计思路。并且封装成了一个 hook vue-use-sync-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 }]

同理,可以增加 omitNullomitUndefined。这三个默认都设为 true

接下来,我们先明白两个概念。在页面第一次加载、执行浏览器前进回退操作时,需要将 url 参数的值转换到当前页面的组件中,在这里我们称其为 decode

在页面中筛选结束点击提交或切换页码时,需要将这些值转换成参数并设置到 url 的参数上,在这里我们称其为 encode

decode

了解后,我们就可以知道上面例子中 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 {};
}

encode

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>。内部将 numberboolean 转换成了 string

type EncodeResult = string | number | boolean | (string | number | boolean)[];

这时候就有问题了,我想将一个比较复杂类型的值同步到 url 上怎么办?这时候就要用到 encodeURIComponentdecodeURIComponent 了,如果你不认识,可以上 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")) })

结语

源码放在 github 了,readme 中还有测试地址,可以来试一试。

以上就是vue实现前端保持筛选条件到url并进行同步参数设计的详细内容,更多关于vue筛选条件url同步参数设计的资料请关注我们其它相关文章!

(0)

相关推荐

  • vue+element table表格实现动态列筛选的示例代码

    需求:在用列表展示数据时,出现了很多项信息需要展示导致表格横向特别长,展示就不够明晰,用户使用起来可能会觉得抓不住自己的重点. 设想实现:用户手动选择表格的列隐藏还是展示,并且记录用户选择的状态,在下次进入该时仍保留选择的状态. 效果图如下: 原: 不需要的关掉默认的勾选: 实现代码: HTML部分就是用一个多选框组件展示列选项 用v-if="colData[i].istrue"控制显示隐藏,把列选项传到checkbox里再绑定勾选事件. <el-popover placemen

  • vue实现前端列表多条件筛选

    本文实例为大家分享了vue实现前端列表多条件筛选的具体代码,供大家参考,具体内容如下 1.先上图: 2.搜索条件绑定的数据是: filterForm:{ schoolName:'',//输入的学校名称 position:'',//选择的区域区域 schoolLevel:"",//选择的学校办别 }, schoolList:[ {schoolName:'青岛市实验高级中学',schoolLevel:"",position:'山东省青岛市城阳区硕阳路69号'}, {sc

  • vue 数据遍历筛选 过滤 排序的应用操作

    vue 中对v-for 遍历数据的处理方式 可以分为两类 : 一.对data 直接赋值(比较笨,但是比较直接) <div id="app"> <ul> <li v-for="item in list">{{item.n}}</li> </ul> </div> </body> <script> var app=new Vue({ el:'#app', data:{ list

  • vue实现单一筛选、删除筛选条件

    本文实例为大家分享了vue实现单一筛选.删除筛选条件的具体代码,供大家参考,具体内容如下 效果预览: 代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="vue.v2.6.10.js"></scrip

  • vue如何通过日期筛选数据

    目录 如何通过日期筛选数据 vue简单数据筛选 如何通过日期筛选数据 此片博客介绍的方法是通过请求后台数据给的状态,然后把自己选择的时间传过去实现筛选的,根据业务逻辑来参考吧! 下篇我们会说下通过vue过滤器来实现的方法! 业务逻辑:首先前端需要获取其用户选择的日期数据,然后通过接口把日期数据传给后端,后端接收数据会返回给前端新的数据,页面在进行渲染.到此功能会是实现了 html部分 <div class="ag_listmain clearfix">           

  • vue实现前端保持筛选条件到url并进行同步参数设计

    目录 前言 基础知识 设计思路 decode encode 详情页返回列表页 结语 前言 在有列表页的系统中,常常为了提高用户体验,需要保持列表页的筛选条件.分页情况.需要做到刷新页面,从详情页返回列表页保留之前的筛选情况.你可能会说 vue 用 keep-alive 缓存列表页不就行了?为什么不好呢? 因为正确的做法是将筛选条件保存在 url 上,这样可以复制给别人直接使用,并且你可以看到几乎所有网站都是使用这种方法.接下来会带大家了解有关 url 参数的基础知识和设计思路.并且封装成了一个

  • 在vue中利用全局路由钩子给url统一添加公共参数的例子

    有的时候我们可能有这样的需求,比如现在url为m.taoyuewenhua.com/#/ 我们需要在用户每次跳转路由的时候监控有没有abc这个参数. 如果有,后端要求我们在以后跳转任何url的时候,都要在url携带上这个参数.就变成m.taoyuewenhua.com/#/&abc=xxx; 这个参数称为"公共参数"; 那么,我们该如何做呢?因为vue中有很多组件.在每个组件都写的话,太麻烦.所以这个时候,全局路由钩子登场了.分别是 router.beforeEach 全局导航

  • 基于JavaScript实现前端数据多条件筛选功能

    有时候也会需要在前端进行数据筛选,增强交互体验.当数据可用的筛选条件较多时,把逻辑写死会给后期维护带来很大麻烦.下面是我自己写的一个简单的筛选器,筛选条件可以根据数据包含的字段动态设置. 仿照京东的筛选条件,这里就取价格区间和品牌作为测试. 代码 代码中主要使用js的过滤器Array.prototype.filter,该方法会对数组元素进行遍历检查,返回一个符合检查条件的新数组,不会改变原数组. // filter() var foo = [0,1,2,3,4,5,6,7,8,9]; var f

  • Vue Element前端应用开发之前端API接口的封装

    1.ABP框架API接口的回顾 ABP是ASP.NET Boilerplate的简称,ABP是一个开源且文档友好的应用程序框架.ABP不仅仅是一个框架,它还提供了一个最徍实践的基于领域驱动设计(DDD)的体系结构模型. 启动Host的项目,我们可以看到Swagger的管理界面如下所示. 上图就是ABP后端框架的API接口的查看页面,从上图可以看到,一般业务对象,都有Get.GetAll.Create.Update.Delete等常见接口,由于这些接口是给前端进行调用的. Vue + Elemen

  • Vue Element前端应用开发之用户管理模块的处理

    1.权限管理模块的设计 我们知道,权限管理一般都会涉及到用户.组织机构.角色,以及权限功能等方面的内容,ABP框架的基础内容也是涉及到这几方面的内容,其中它们之间的关系基本上是多对多的关系,它们的关系如下所示. 权限模块里面包含的一些主对象表和中间表,中间表主要用来存储两个对象之间的多对多关系,如角色包含多个用户,用户属于多个机构,机构包含多个角色等等. 结合ABP后端提供的接口,Vue前端我们要实现基础的用户.组织机构.角色.功能权限等内容的管理,以及维护它们之间的关系.Vue前端对于权限管理

  • 详解React Angular Vue三大前端技术

    一.[React] React(也被称为React.js或ReactJS)是一个用于构建用户界面的JavaScript库.它由Facebook和一个由个人开发者和公司组成的社区来维护. React可以作为开发单页或移动应用的基础.然而,React只关注向DOM渲染数据,因此创建React应用通常需要使用额外的库来进行状态管理和路由,Redux和React Router分别是这类库的例子. 基本用法 下面是一个简单的React在HTML中使用JSX和JavaScript的例子. Greeter函数

  • Vue Element前端应用开发之图标的维护和使用

    概述 Vue-Awesome 是基于 Vue.js 的 SVG 图标组件,内置图标来自 Font Awesome. 本篇随笔先来上一个图标管理的界面效果,然后在逐一进行介绍Element内置图标和Vue-Awesome的图标吧. Element图标管理界面如下: 基于Vue-Awesome的图标管理如下所示. 其中查询提供了名称进行图标查询,以及限制一次性展示多少个,另外提供一个自定义颜色选项,从而可以改变图标的展示颜色. 1.Vue-Awesome的使用介绍 Vue-Awesome 的 npm

  • Vue Element前端应用开发之常规Element界面组件

    目录 1.列表界面和其他模块展示处理 2.常规界面组件的使用 1)表单和表单项.单文本框 2)下拉列表控件的绑定 3)图片展示 4)第三方扩展控件 3.自定义组件的创建使用 1.列表界面和其他模块展示处理 常规的列表展示界面,一般分为几个区域,一个是查询区域,一个是列表展示区域,一个是底部的分页组件区域.查询区域主要针对常规条件进行布局,以及增加一些全局或者批量的操作,如导入.导出.添加.批量添加.批量删除等按钮:而其中主体的列表展示区域,是相对比较复杂一点的地方,需要对各项数据进行比较友好的展

随机推荐