這個實現(xiàn)不對,要的是excel里面的高亮重復(fù)項效果

前言

項目里的一個比較數(shù)據(jù)重復(fù)的功能,根據(jù)勾選的列,選擇表格行數(shù)據(jù),然后點擊高亮重復(fù)項對比當(dāng)前選中的行里面的數(shù)據(jù),拋開業(yè)務(wù)部分這個功能提取后長這樣子

原型評審的時候,產(chǎn)品經(jīng)理就說了一句,這里根據(jù)選擇的列,勾選表格數(shù)據(jù),校驗數(shù)據(jù)重復(fù)

開發(fā)順利開發(fā)完了,測試人員也測試通過標(biāo)記當(dāng)前任務(wù)結(jié)束了,結(jié)果過來一周多,產(chǎn)品經(jīng)理跑過來說,這個功能實現(xiàn)的不對,我要的是 Excel 里面的高亮重復(fù)項功能,像這個操作,噼里啪啦演示了一波,我的天吶,怎么原型評審的時候不這么演示一下呢

項目開發(fā)周期這么緊張,這功能項關(guān)聯(lián)的業(yè)務(wù)邏輯也需要調(diào)整,項目進(jìn)度是不會因為這個功能調(diào)整了就改變上線時間的,還想抓緊時間改,當(dāng)場我就EMO了

思路梳理

工作上的事情不能帶情緒,雖然一萬個不愿意,還是得抽空把產(chǎn)品經(jīng)理的需求給搞定了,我們來看下 Excel 中的高亮重復(fù)項功能的實現(xiàn)效果是怎樣的

通過 WPS Excel 中的操作可以看出,表格數(shù)據(jù)高亮重復(fù)項可以選中一個數(shù)據(jù)列實現(xiàn)當(dāng)前數(shù)據(jù)列
數(shù)據(jù)重復(fù)高亮,也可以多列對比重復(fù)項

代碼實現(xiàn)

根據(jù) Excel 的高亮重復(fù)項操作邏輯我們分析得出,代碼核心實現(xiàn)需要兩個步驟:1.獲取重復(fù)項數(shù)據(jù);2.設(shè)置表格高亮

項目需求功能如下效果

通過實際項目需求操作模式來進(jìn)行分析,首先基本的表格展示,多選功能,高亮列的選中,高亮重復(fù)項操作按鈕, vue 文件中 template 代碼如下

<el-table
  border
  ref="multipleTable"
  :data="tableData"
  @selection-change="handleSelectionChange"
  style="width: 500px"
>
  <el-table-column type="selection" width="55"> </el-table-column>
  <el-table-column label="日期">
    <template slot-scope="scope">{{ scope.row.date }}</template>
  </el-table-column>
  <el-table-column label="姓名">
    <template slot-scope="scope">
      <div
        v-if="scope.row.back"
        class="background-color-ffff00"
      >
        {{ scope.row.name }}
      </div>
      <div v-else>{{ scope.row.name }}</div>
    </template>
  </el-table-column>
  <el-table-column label="昵稱">
    <template slot-scope="scope">
      <div
        v-if="scope.row.back2"
        class="background-color-ffff00"
      >
        {{ scope.row.nickName }}
      </div>
      <div v-else>{{ scope.row.nickName }}</div>
    </template>
  </el-table-column>
</el-table>

<div style="margin-top: 20px; display: flex">
  <el-checkbox-group
    v-model="checkList"
    style="margin-right: 20px; margin-top: 10px"
  >
    <el-checkbox label="name">姓名</el-checkbox>
    <el-checkbox label="nickName">昵稱</el-checkbox>
  </el-checkbox-group>
  <el-button @click="highLightData">高亮重復(fù)項</el-button>
  <el-button @click="clearHighLightData">清除高亮重復(fù)項</el-button>
</div>



<script>
export default {
  name: 'Table1',
  components: {},
 data () {
    return {
      checkList: [],
      tableData: [
        {
          id: '1',
          date: '2016-05-03',
          name: '張三',
          nickName: '李四'
        },
        {
          id: '2',
          date: '2016-05-02',
          name: '李四',
          nickName: '曹操'
        },
        {
          id: '3',
          date: '2016-05-04',
          name: '張三',
          nickName: '趙云'
        }
        
...

表格單元格數(shù)據(jù)高亮是通過設(shè)置的一個自定義變量的來實現(xiàn)的,由于實際項目需求中表格數(shù)據(jù)只有兩列需要高亮顯示,因此這里使用兩個控制變量來實現(xiàn),通過 checkList 選中的 name 值對應(yīng)不同的變量,通過 v-if 的方式控制高亮的 div 背景樣式

接下來,來分析對應(yīng)的操作功能,高亮重復(fù)項功能通過選中數(shù)據(jù)和表格列后,只需要一個點擊,所有的邏輯都在這個這個按鈕的點擊觸發(fā)函數(shù)里完成,開始JS邏輯的實現(xiàn)分析

1.獲取重復(fù)項數(shù)據(jù)

基于選中列和行的對比的表格中的重復(fù)數(shù)據(jù), 高亮重復(fù)項 按鈕點擊后先校驗數(shù)據(jù)行是否選中,以及高亮重復(fù)項的列是否選中,這個是基礎(chǔ)的校驗,所有操作,由于是基于案例分析單獨(dú)寫的 demo,校驗失敗使用的 console.warn

通過 multipleSelection 表格選中行數(shù)據(jù)和 checkList 選中列篩選出重復(fù)項內(nèi)容,得到高亮重復(fù)項數(shù)據(jù)后,接下來獲取到對應(yīng)的行索引并記錄,并把當(dāng)前行對應(yīng)的列的控制變量 back* 設(shè)置為 true


if (this.multipleSelection.length < 2) {
  console.warn('先選擇至少兩行數(shù)據(jù)')
  return false
}

if (this.checkList.length === 0) {
  console.warn('請先選擇一列')
  return false
}


// 獲取重復(fù)項內(nèi)容
const arr = []
const arr2 = []
this.multipleSelection.forEach((v, k) => {
  this.checkList.forEach(v2 => {
    if (arr.indexOf(v[v2]) === -1) {
      arr.push(v[v2])
    } else {
      if (arr2.indexOf(v[v2]) === -1) {
        arr2.push(v[v2])
      }
    }
  })
})
console.log('arr --xxx ', arr)
console.log('arr2 -- ', arr2)

this.multipleSelection.forEach((v, k) => {
  // 設(shè)置重復(fù)項所在的數(shù)據(jù)行
  arr2.forEach(item => {
    this.checkList.forEach(v2 => {
      if (v2 === 'name') {
        if (item === v[v2]) {
          v.back = true
        }
      }

      if (v2 === 'nickName') {
        if (item === v[v2]) {
          v.back2 = true
        }
      }
    })
  })

})

2.設(shè)置表格高亮

上面的步驟中已經(jīng)把當(dāng)前行對應(yīng)的列的控制變量 back* 設(shè)置為 true, 這個時候可以在設(shè)置重復(fù)項所在的數(shù)據(jù)行的同時把當(dāng)前高亮重復(fù)項的標(biāo)記行數(shù)據(jù)替換到綁定的表格數(shù)據(jù)中,這樣可以共用一個循環(huán)

// 更新表格行數(shù)據(jù)為高亮數(shù)據(jù)
const i = this.tableData.findIndex(item => item.id === v.id)
this.tableData.splice(i, 1, v)

這時候?qū)τ谡麄€數(shù)據(jù)層,表格數(shù)據(jù)已經(jīng)根據(jù)選中的行和列對比出高亮的數(shù)據(jù)項了,但是, 此時頁面中的表格并沒有根據(jù)數(shù)據(jù)的變化而重新渲染,手動處理一下表格數(shù)據(jù),讓表格數(shù)據(jù)渲染出高亮設(shè)置后的效果

// 更新表格視圖,實現(xiàn)高亮
const highlightArr = JSON.parse(JSON.stringify(this.tableData))
this.tableData = []
this.tableData = highlightArr

整個表格數(shù)據(jù)列高亮重復(fù)項的功能總算完成了,我們來看下完整的 Demo 操作效果

演示代碼地址

https://github.com/gywgithub/vue-admin-element/blob/main/src/views/Table1.vue

思考總結(jié)

文章中的高亮重復(fù)項是兩列對比,如果是更多列對比,例如表格數(shù)據(jù)是動態(tài)配置列顯示,基于動態(tài)列,動態(tài)查詢指定的數(shù)據(jù),又是動態(tài)自定義高亮重復(fù)項,就像 Excel 表格中的高亮重復(fù)項功能一樣,可以隨便根據(jù)表格數(shù)據(jù)進(jìn)行高亮重復(fù)項操作,像這種情況實現(xiàn)方面的可能就不能參考當(dāng)前文章解決方案了,那遇到這種情況怎么解決呢?

我在做這里的項目需求功能的時候想到過一個思路:根據(jù)表格數(shù)據(jù)行索引和數(shù)據(jù)列索引的方式,去對比數(shù)據(jù)重復(fù)項,根據(jù)數(shù)據(jù)重復(fù)項記錄需要表格中需要高亮的數(shù)據(jù)單元格位置,然后把這些記錄的位置對應(yīng)的單元格進(jìn)行高亮處理

讀者們你們還有別的更好的思路或者實現(xiàn)方案嗎? 歡迎大家評論區(qū)討論交流,一起學(xué)習(xí)共同進(jìn)步 ^-^

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容