前端通关日记之优雅添加数组元素

起源

需求是须要在前端输入一个数组,该数组做为参数请求后端接口。项目前端UI框架采用element-ui, 笔者实现的方式是 "巧用"<el-select> 标签,并添加了多选等一系列属性,代码以下:javascript

<el-select v-model.trim="scope.row.query" multiple // 多选 filterable default-first-option allow-create placeholder="请输入变量查询语句">
</el-select>
复制代码

这样的话用户经过循环 输入 -> 回车 动做,便可在一个输入框内为数组添加元素。示例以下:html

( 该项目详细信息可参阅项目起源 )前端

能够看到不管是考虑交互体验仍是前端美观性,这种实现方式都是很是良好的。java

可是,遇到了下面的问题。element-ui

问题

当数组中存在一样的参数时, 这种方法就行不通了,由于 el-select 会帮你自动去重,示例以下:后端

这 ... ...数组

好吧 ... ...框架

由于笔者项目中是会存在这种应用场景的(详情请参阅 笔者这篇做文dict_get 函数中的 locators 参数),因此并不能默认数组中不会出现一样的元素。函数

行吧那怎么解决呢???post

解决思路

笔者认为,任何伟大的问题的解决思路必定是 简洁且清晰明了 的。

首先,我须要对本身进行一次深入的灵魂拷问

  1. Q:是改前端/后端,仍是一块儿都改呢?
    A:(os : 后端怎么都不能由于这个状况去作任何改动,太不合理了。)好的,那就修改前端。
  2. Q:前端具体怎么改呢,是本身实现一个组件仍是在原有组件上作一些处理呢?
    A:(os : 我才不要本身再实现一个组件呢,如今这个多好看。)好的,那就作一些处理。

通过深入的灵魂拷问后,笔者决定在原有基础上尝试进行一些处理,看可否解决问题。

查阅官方文档后,我发现 el-select 标签中可自定义 change 事件,以下所示:

那看来能够拿这个事件作点文章了嘿。

最终方案

笔者通过 深思熟虑 后,决定利用 el-select 中的 change 事件,给数组中各个元素分别加上一个 后缀,这样的话便可达到 数组中无重复元素 的目的。

因考虑到后缀惟一性、复杂性以及前端观赏性,而且因笔者基本没见过带括号的键名, 故 后缀 采用 括号加数字的形式 添加 ( 如:(1) )。

这里主要运用了 search 函数进行 后缀查找,若是后缀不存在的话则添加后缀,存在的话则校准后缀。 具体实现代码以下(js水平不高请轻喷 = =):

// 添加后缀
addSuffix(query){
  const isValidQuery = query.constructor === Array && query.length > 0;
  if (isValidQuery){
    query.forEach((item, index) => {
      const suffixStartIndex = item.search(/\([0-9]+\)/);
      const expectedSuffix = '(' + (index + 1).toString() + ')';
      if (suffixStartIndex === -1){
        query[index] = item + expectedSuffix;
      }else{
        query[index] = item.substring(0, suffixStartIndex) + expectedSuffix;
      }
    })
  }
  return query
}
复制代码

而后在 el-select 标签中添加 change 事件:

<el-select v-model.trim="scope.row.query" @change="addSuffix(scope.row.query)" multiple // 多选 filterable default-first-option allow-create placeholder="请输入变量查询语句">
</el-select>
复制代码

具体效果仍是交给动图去说话:

这样的话,除非你特地去输入带有 (number) 的键(我是没见过),否则基本能够 无公害 解决问题。

收拾烂摊子

接下来,咱们须要在向后端传递参数时将 后缀 去除,这里运用了 replace 函数,示例代码以下:

// 删除后缀
    self.form.setGlobalVars.forEach((setGlobalVar) => {
      setGlobalVar.query.forEach((query, index) => {
        setGlobalVar.query[index] = query.replace(/\([0-9]+\)/, "");
      })
    });
复制代码

然而事情到这里就结束了吗? 咱们还须要在获取后端数据时,将后缀加上,以供前端展现,这里直接运用了以前封装好的 addSuffix 函数。代码以下:

// 加后缀
    data.setGlobalVars.forEach((setGlobalVar) => {
      setGlobalVar.query = this.addSuffix(setGlobalVar.query)
    });
复制代码

至此。这个问题算是 “完美” 解决了。

记录了一下,从发现问题到解决问题共耗时 2小时

从解决问题到完成这篇文章共耗时 1成天

欢迎你们扫码关注个人公众号「智能自动化测试」,回复:测试进阶教程,便可免费得到 进阶教程 ~

-- 2019-5-12
复制代码

祝全部伟大的母亲节日快乐!妈妈我爱你!

相关文章
相关标签/搜索