公司系統在用elementui作後臺開發,難免遇到一些須要本身去根據原有的功能上,加一些交互的功能。
今天來介紹下我在用elementUi裏的Tag標籤與多選框交互的過程,東西聽上去很簡單,但就是越簡單的東西越容易出一些問題。官方tag文檔: elementUi-tag標籤
效果圖:數組
1、多選框勾選,出現對應的tag:
1.利用watch監聽多選框綁定的值 A(數組)的變化;
2.根據 A的變化,循環拿到勾選多選框的id對應的name,將id以及對應的name組成新的對象數組;
3.將上一步獲得的對象數組,去重(產品要求,出現的tag裏不能有重複的)獲得結果 B;
4.將 B賦值給tags,循環展現出來;2、點擊tag上的刪除按鈕,刪除當前的tag,並將對應勾選的多選框取消勾選:
1.點擊tag刪除的按鈕的時候,拿到當前tag的id C;
2.執行方法,去除掉A裏的C;
3.watch事件從新進入到第一步的方法;flex總結:監聽多選框對應的model A,根據A的變化,取到對應的id與name,賦值給tag做展現,tag的刪除事件反過來在去控制A的變化,從新進入watch事件裏的方法ui
聽起來挺簡單,思路大概也明確,先講上述思路對應的代碼,後邊再講遇到的問題、坑this
複製整一塊代碼到你的elementUi項目裏就能看到效果
<template> <div> <el-row type="flex" justify="bettwen"> <el-col :span="15"> <!-- 表單 --> <el-form :model="tempForm" ref="tempForms"> <el-form-item label="請選擇人員"> <!-- 多選人員 --> <el-checkbox-group v-model="tempForm.checkboxGroup5" size="small"> <el-checkbox border v-for="(item,index) in checkBox" @change="perChange(item)" :label="item.id" :key="index">{{item.name}}</el-checkbox> </el-checkbox-group> <!-- 多選人員 end--> </el-form-item> </el-form> <!-- 表單 end--> <!-- tag展現區 --> <el-row> <el-tag class="tagClass" v-for="(tag,index) in tags" :key="index" closable @close="handleClose(tag)" :type="tag.id"> {{tag.name}} </el-tag> <el-button v-if="tags.length>0" @click="clearAll" plain>所有刪除</el-button> </el-row> <!-- tag展現區 end--> </el-col> </el-row> </div> </template> <script> export default { name: 'kk', mounted() {}, data() { return { msg: 'Welcome to Your Vue.js App', tags: [], tempForm: { checkboxGroup5: [], //選擇的人員 }, detailData: [], checkBox: [{ name: '小紅', id: '101' }, { name: '小黃', id: '100' }, { name: '小明', id: '102' }, { name: '小明', id: '102' } ], } }, methods: { clearAll() { //所有清空數據 this.tags = [] this.tempForm.checkboxGroup5 = [] }, perChange(item) { this.detailData.push(item) }, handleClose(tag) { //標籤的刪除事件 // 去掉當前刪除的tag let yourChoseTags = this.tempForm.checkboxGroup5 this.tempForm.checkboxGroup5 = yourChoseTags.filter(item => { if (tag.id !== item) { return true } }) }, delRepeat(arr) { //數組對象去重 return Object.values( arr.reduce((obj, next) => { var key = JSON.stringify(next); return (obj[key] = next), obj; }, {}), ); }, moreArr() { let yourChose = this.tempForm.checkboxGroup5 let tempTags = [] tempTags = this.baseDataDetail(yourChose, this.checkBox, tempTags) this.detailData = tempTags }, baseDataDetail(yourChose, baseData, callBack) { //封裝的數組方法 let temp = callBack // 循環兩個數據拿到選擇的checkbox的id對應的初始數據 yourChose.forEach(item => { baseData.forEach(itemSecond => { if (item === itemSecond.id) { temp.push(itemSecond) } }) }) return temp }, }, watch: { detailData() { let tempArr = Object.assign([], this.detailData) tempArr = this.delRepeat(tempArr) // console.log(tempArr) this.tags = tempArr }, "tempForm.checkboxGroup5" () { this.moreArr() }, } } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> .tempArea { /*width: 100%;*/ } .tagClass{ margin-right: 10px; } </style>
1.我在多選框綁定值 tempForm.checkboxGroup5的監聽事件裏的方法的最後,獲得了一個可能會有重複數據(重複id跟name),再將這個含有重複數據數組對象賦值給另外一個數組 detailData,在watch監聽這個數組,去完重後,賦值給tags作展現。
爲何這樣作,是由於,咱們的需求裏,除了在當前頁面多選框選擇人員,還有一個選擇全公司員工的組件,這樣無論從哪一個渠道選擇的人員都能最後將結果指向 detailData,保證渲染正確2.數組對象去重,初始數據裏可能會有重id、重名的對象(小明),即使綁定多選框的model值裏不會有重複的id,但在 利用id取對應name的時候,仍是會檢測出多條,這樣tag就可能會顯示重複的
因此利用這個方法,就能保證最後處理好的數據沒有重複的,tag不會顯示多個同樣的,
但這個方法有點不靈活的地方就是,你要處理的數據({id:1,name:'小明',type:now})必須id、name,type都重複的時候,纔會被去重,
拓展:可根據你設置的數組對象裏的某個屬性動態去重spa
//數組對象去重:id、name,type都重複的時候,纔會被去重 delRepeat(arr) { return Object.values( arr.reduce((obj, next) => { var key = JSON.stringify(next); return (obj[key] = next), obj; }, {}), ); } //拓展:根據你設置的數組對象裏的name屬性動態去重 baseDel(arr) { const res = new Map(); return arr.filter((item) => !res.has(item.name) && res.set(item.name, 1)) },
3.我一開始是在多選框的change事件上來作tag的展現邏輯,由於change事件裏能夠同時拿到當前選擇的name和id,可是,change的時候,你不知道這是在勾選仍是在取消勾選,這樣tags的展現就會出問題;
這個邏輯可能不太完美,由於有可能你的人員是從其餘組件裏選來的,因此當你刪除tag的時候,會可能出問題(暫時先不討論這種狀況)code
歡迎你們來指正和補充,或者你的業務需求以及解決方式,撒花component