弹窗分页保留其他页面勾选的数据(vue)

如图所示,这是个常见的多选todolist

不过这里多了个要求,弹窗上下页面切换的时候需要保留勾选结果

这其实也不难,但是如果每次都手动写一遍却有点恼人,这次捋一下思路,并把核心代码记录一下,方便下次翻找

核心思想

  1. 在服务器返回的数据之外再维护一个列表A,存储被钩上的数据
  2. 在请求接口时候给服务器返回数据钩上已选的
  3. 点击全选或者单个勾选(或取消勾选)时候再次把当前页面的勾选数据同步给列表A
  4. 那如何同步呢?重点,后面针对性说同步函数

弹窗封装

data数据说明

  • data对应的数据有;
  • params: 外部传入接口请求的参数;
  • single: 是否单选;
  • pickedArr:承接外部传入的已选中元素数组后变成已选元素数组
  • selectedItems:弹窗内已选中的元素数组;
  • form: 弹窗内查询列表的参数;

1.对外提供show方法来调用,接受几个参数,

1.1config.single是否支持单选

1.2.params 接口请求需要的额外参数

1.3.外面已选的列表(最好是完整列表,数组元素包括id和对应的文字)

1.4 根据1.3进行一些过滤(有时候弹窗是个二级弹窗,需要根据params参数进行置空或过滤)最后把过滤后的数组作为当前弹窗已勾选列表来存储数据

show函数程序入口

  • 初始化配置参数

  • 初始化已选数据

  • 请求列表

  • 显示弹窗

    function show(config) {
    this.showMaterialPopup = true;
    const { params, single, pickedArr } = config;
    //配置参数覆盖
    // Array.isArray(filterids) ? (this.filterids = []) : (this.filterids = []);
    params ? (this.params = params) : (this.params = {});
    single ? (this.single = true) : (this.single = false);
    Array.isArray(pickedArr) ? (this.pickedArr = pickedArr) : (this.pickedArr = []);
    ///////
    //初始化弹窗的已选数据
    ///////
    const firstPickItem = this.pickedArr[0];
    //根据params和已选中的第一个做一些判断或者过滤
    //这里的代码是个二级弹窗,可以参考,
    if (firstPickItem && firstPickItem.materialId && firstPickItem.materialId == params.materialId) {
    //把传入已选上的元素的checked都钩上
    this.selectedItems = this.pickedArr.map((item) => {
    item.checked = true; //够上了
    return { ...item };
    });
    } else {
    //不符合要求的话,就忽略传入的已选中元素
    this.selectedItems = [];
    }

    复制代码
      //初始化列表查询数据
      this.form.pageNum = 1;
      //查询列表数据
      this.getList();

    }

getList函数

  • 获取元素时候,给【服务器返回的数据list】做勾选初始化

  • 这里就处理了点击上下页面和第一次加载时候可以钩上已选数据

    //获取元素时候,给【服务器返回的数据list】做勾选初始化
    //这里就处理了点击上下页面和第一次加载时候可以钩上已选数据
    function getlList() {
    //合并请求参数
    listAJAXFN({ ...this.form, ...this.params }).then((res) => {
    if (res.code == 200) {
    let { rows, total, size } = res.data;
    // 创建选中序列号的Set,用于O(1)快速查找
    //数组转set,方便快速判断
    const selectArrSet = new Set(this.pickedArr.map((item) => item.id));
    // 在单次迭代中处理所有行
    rows = rows.map((item) => {
    //如果已选元素里有这个元素,就钩上
    item.checked = selectArrSet.has(item.id);
    return item;
    });
    this.list = rows.filter((item) => !this.filterids.includes(item.id));
    }
    });
    }

同步函数

  • 1.把本页勾选了的数据给外面传入已勾选的数据对应勾选上

  • 2.把本页存在且勾选了,但是外层传入的数组里面没有元素找出来合并到已选数据上面

  • 3.全选或者单个勾选(取消或者够上)时候调用就可以了

    //更新已选择的序列号
    //在勾选过程中
    function updateselectedSerialNumWhenPick() {
    //步骤一
    //判断有没有勾选上,针对外面已有选中数据
    // 合并checked属性到this.pickedArr中存在的元素
    this.pickedArr.forEach((aItem) => {
    //从本页勾选的数组中找到外层传入的勾选数据进行匹配
    //如果存在就给他勾选(因为进入页面后,用户可能取消掉了也有可能)
    //这里只勾选就好了,不需要管不勾选的,不勾选的也不是我们想要的
    const matchingBItem = this.list.find((bItem) => bItem.id === aItem.id);
    if (matchingBItem) {
    aItem.checked = matchingBItem.checked;
    }
    });
    //步骤二,针对本页勾选的,但是外层数据没有传入的数据,
    //要把它们找出来,并合并到一选数组里面
    // 获取当前页面中中有而a中没有的元素
    //够上了,且外面已勾选的没有它的数组
    const uniqueToB = this.list.filter((item) => item.checked).filter((bItem) => !this.pickedArr.some((aItem) => aItem.id === bItem.id));
    //更新已选中数据
    this.pickedArr = [...this.pickedArr, ...uniqueToB];
    }

确认函数

把已选好的数组里面的checked过滤下,传递出去,外面直接接收就行了

复制代码
onMulitComfirm() {
			//从已选元素里面拿
			const arr =this.pickedArr.filter((item) => item.checked);
			if (arr.length == 0) {
				this.$u.toast('请勾选序列号');
				return;
			}
			this.$emit('choose', this.material, arr);
			this.showMaterialPopup = false;
}
相关推荐
Wiktok2 小时前
【Wit】pure-admin后台管理系统前端与FastAPI后端联调通信实例
前端·vue3·pureadmin
IT_陈寒2 小时前
Vite 5.0重磅升级:8个性能优化秘诀让你的构建速度飙升200%!🚀
前端·人工智能·后端
Run Freely9372 小时前
Ajax-day2(图书管理)-弹框显示和隐藏
前端·javascript·ajax
GDAL2 小时前
Knockout.js Virtual Elements 详解
前端·javascript·knockout
百思可瑞教育3 小时前
Vue.config.js中的Webpack配置、优化及多页面应用开发
前端·javascript·vue.js·webpack·uni-app·北京百思教育
患得患失9493 小时前
【前端】【高德地图WebJs】【知识体系搭建】面要素知识点——>多边形,圆形, 矩形,图形编辑器
前端·编辑器·高德地图·amap
歪歪1003 小时前
webpack 配置文件中 mode 有哪些模式?
开发语言·前端·javascript·webpack·前端框架·node.js
歪歪1004 小时前
如何配置Webpack以实现按需加载模块?
开发语言·前端·webpack·node.js
面向星辰6 小时前
html各种常用标签
前端·javascript·html