前端通關日記之優雅新增陣列元素

泰斯特test發表於2019-05-12

起源

需求是需要在前端輸入一個陣列,該陣列作為引數請求後端介面。專案前端UI框架採用element-ui, 筆者實現的方式是 "巧用"<el-select> 標籤,並新增了多選等一系列屬性,程式碼如下:

<el-select
    v-model.trim="scope.row.query"
    multiple // 多選
    filterable 
    default-first-option
    allow-create 
    placeholder="請輸入變數查詢語句">
</el-select>
複製程式碼

這樣的話使用者通過迴圈 輸入 -> 回車 動作,即可在一個輸入框內為陣列新增元素。示例如下:

前端通關日記之優雅新增陣列元素

( 該專案詳細資訊可參閱專案起源 )

可以看到無論是考慮互動體驗還是前端美觀性,這種實現方式都是非常良好的。

前端通關日記之優雅新增陣列元素

但是,遇到了下面的問題。

問題

當陣列中存在同樣的引數時, 這種方法就行不通了,因為 el-select 會幫你自動去重,示例如下:

前端通關日記之優雅新增陣列元素

這 ... ...

好吧 ... ...

前端通關日記之優雅新增陣列元素

因為筆者專案中是會存在這種應用場景的(詳情請參閱 筆者這篇作文dict_get 函式中的 locators 引數),所以並不能預設陣列中不會出現同樣的元素。

行吧那怎麼解決呢???

解決思路

筆者認為,任何偉大的問題的解決思路一定是 簡潔且清晰明瞭 的。

首先,我需要對自己進行一次深刻的靈魂拷問

  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
複製程式碼

前端通關日記之優雅新增陣列元素

祝所有偉大的母親節日快樂!媽媽我愛你!

相關文章