vue實(shí)現(xiàn)下拉框的多選功能(附后端處理參數(shù))
本次演示共涉及三個(gè)界面,一個(gè)是主表用于展示數(shù)據(jù)的,一個(gè)是表單用于新增數(shù)據(jù)的,另一個(gè)則是編輯用于修改表格數(shù)據(jù)的,先上效果圖:
1、主表界面(數(shù)據(jù)來(lái)源于數(shù)據(jù)庫(kù)查表返回):
<el-table :data="tableData" border> <el-table-column type="index" label="序號(hào)"></el-table-column> <el-table-column label="姓名" prop="name"></el-table-column> <el-table-column label="愛好" prop="stringHobby"></el-table-column> </el-table>
2、新增數(shù)據(jù)界面(點(diǎn)擊新增按鈕觸發(fā)):
如果要實(shí)現(xiàn)對(duì)“愛好”這一屬性進(jìn)行下拉框多選,那么前端核心代碼可這么寫:
//html部分 <el-dialog title="新增" :visible.sync="addDialog"> <el-form-item label="愛好:"> <el-select v-model="formData.hobby" multiple> <el-option v-for="item in hobbyList" :key="item.value" :label="item.label" :value="item.value" ></el-option> </el-select> </el-form-item> </el-dialog> //js部分 export default { data() { return { addDialog: false, formData: [], hobbyList: [ { value: "1", label: "籃球" }, { value: "2", label: "排球" }, { value: "3", label: "足球" } ] } } }
如上圖所示,你選擇了籃球和排球,那么籃球和排球所對(duì)應(yīng)的碼值“1”和“2”就會(huì)存入hobby這個(gè)屬性中,此時(shí)formData.hobby的類型是一個(gè)列表,其值為["1", "2"],這個(gè)值是要作為參數(shù)傳到后臺(tái)作處理的。
3、編輯數(shù)據(jù)界面(點(diǎn)擊編輯按鈕觸發(fā)):
編輯界面要實(shí)現(xiàn)下拉框多選功能,和新增界面是類似的,但難點(diǎn)有兩點(diǎn):1、當(dāng)點(diǎn)擊上方的編輯按鈕時(shí),如何將主表界面的數(shù)據(jù)全部且正確地帶過(guò)去?此時(shí)編輯界面的表格數(shù)據(jù)要和主表界面的數(shù)據(jù)完全一致并且“愛好”這一列自動(dòng)選擇好,用戶可直接在現(xiàn)有的數(shù)據(jù)上作編輯而不是進(jìn)去后"愛好"這一列都是空的;2、編輯好后整個(gè)表格數(shù)據(jù)的保存問(wèn)題會(huì)比新增要復(fù)雜,這些字段在前端如何處理才能被后臺(tái)接收且方便保存?
針對(duì)難點(diǎn)一,我們會(huì)想到將主表中:data="tableData"的tableData賦值給這個(gè)編輯表格的:data,但是這樣只能將“姓名”帶過(guò)去,因?yàn)檫@個(gè)屬性在兩個(gè)界面都是字符串類型直接映射就好,“愛好”屬性則不同,它在主表是字符串,到了編輯表必須轉(zhuǎn)換為字符列表才行。如張三的愛好是足球和籃球,在主表中屬性值為"3, 1"(字符串類型),需要轉(zhuǎn)為["3", "1"](字符列表類型),這樣系統(tǒng)才能根據(jù)你設(shè)置的hobbyList中的value-label進(jìn)行自動(dòng)匹配,核心代碼如下:
//html部分 <el-dialog title="編輯" :visible.sync="editDialog"> <el-table :data="editData" border> <el-table-column type="index" label="序號(hào)"></el-table-column> <el-table-column label="姓名" prop="name"></el-table-column> <el-table-column label="愛好" prop="hobby"> <template slot-scope="{ row }"> <el-select v-model="row.hobby" multiple> <el-option v-for="item in hobbyList" :key="item.value" :label="item.label" :value="item.value" ></el-option> </el-select> </template> </el-table-column> </el-table> </el-dialog> //js部分 export default { data() { return { editDialog: false, editData: [], } } methods: { //獲取編輯頁(yè)面的表格數(shù)據(jù) edit() { this.editDialog = true; //將主表數(shù)據(jù)賦到編輯頁(yè)面的表格數(shù)據(jù)中 this.editData = this.tableData; //循環(huán)獲取表格的每條記錄 for (let i = 0; i < this.editData.length; i++) { //以下代碼的目的是將每條記錄的愛好這一屬性的類型由字符串轉(zhuǎn)換為列表對(duì)象,如替換前為"1,2,3",那么替換后為["1","2","3"] let str = this.editData[i].hobby.split(","); let newArray = []; //循環(huán)獲取每條記錄的愛好集合 for (let j = 0; j < str.length; j++) { newArray.push(str[j]); } this.editData[i].hobby = newArray; } } } }
針對(duì)難點(diǎn)二,實(shí)現(xiàn)方法就是對(duì)表格的每條記錄都要處理一下(主要是處理"愛好"這一列),然后做循環(huán)逐條存庫(kù),此處沒(méi)必要長(zhǎng)篇大論,直接上代碼:
//html部分 <el-button @click="editSave" icon="el-icon-edit"> 保存 </el-button> //js部分 export default { methods: { //編輯記錄時(shí)的保存方法 editSave() { var rows=[] var saveData=[] for(let i=0; i< this.editData.length; i++){ var object = new Object() //獲取當(dāng)前記錄的所有屬性 rows[i] = this.editData[i] object.name = rows[i].name object.hobby = rows[i].hobby saveData.push(object) } //將數(shù)據(jù)組合成一個(gè)列表對(duì)象(savaData)傳給后端 axios({ method: "post", url: "/dealData/editData", params: savaData }) .then(function(response) { this.$msgbox({ title: '系統(tǒng)提示', message: response.data.message, type: 'success', }) }) .catch(function(error) { console.log(error) }) } } }
以下是完整的前后端代碼,可拿來(lái)直接運(yùn)行:
前端:
<template> <div> <div class="class1"> <el-button @click="addDialog = true" type="primary" size="small" round icon="el-icon-edit" > 新增 </el-button> <el-button @click="edit" type="primary" size="small" round icon="el-icon-edit" > 編輯 </el-button> </div> <div> <el-table class="class2" :header-cell-style="{ 'text-align': 'center' }" :cell-style="{ 'text-align': 'center' }" :data="tableData" :show-header="true" :background="true" border width="800px" tooltip-effect="light" > <el-table-column type="index" label="序號(hào)" width="100px"> </el-table-column> <el-table-column label="姓名" prop="name" width="200px"> </el-table-column> <el-table-column label="愛好" prop="stringHobby" width="500px"> </el-table-column> </el-table> <el-dialog title="新增" :visible.sync="addDialog" :show-close="true" append-to-body width="30%" center > <div class="class3"> <el-form style="margin-left: 50px"> <el-form-item label="姓名:"> <el-input v-model="formData.name" style="width:400px; margin-left:-70px" ></el-input> </el-form-item> <el-form-item label="愛好:"> <el-select v-model="formData.hobby" multiple style="width:400px;margin-left:-70px" > <el-option v-for="item in hobbyList" :key="item.value" :label="item.label" :value="item.value" ></el-option> </el-select> </el-form-item> </el-form> </div> <div class="class3"> <el-button @click="addSave" type="primary" size="small" round icon="el-icon-edit" > 保存 </el-button> </div> </el-dialog> <el-dialog title="編輯" :visible.sync="editDialog" :show-close="true" append-to-body center > <el-table :header-cell-style="{ 'text-align': 'center' }" :cell-style="{ 'text-align': 'center' }" :data="editData" :show-header="true" :background="true" stripe border tooltip-effect="light" > <el-table-column type="index" label="序號(hào)"></el-table-column> <el-table-column label="姓名" prop="name"></el-table-column> <el-table-column label="愛好" prop="hobby"> <template slot-scope="{ row }"> <el-select v-model="row.hobby" multiple style="width:300px"> <el-option width="300px" v-for="item in hobbyList" :key="item.value" :label="item.label" :value="item.value" ></el-option> </el-select> </template> </el-table-column> </el-table> <div class="class3"> <el-button @click="editSave" type="primary" size="small" round icon="el-icon-edit" > 保存 </el-button> </div> </el-dialog> </div> </div> </template> <script> export default { data() { return { addDialog: false, editDialog: false, tableData: [], formData: [], editData: [], hobbyList: [ { value: "1", label: "籃球" }, { value: "2", label: "排球" }, { value: "3", label: "足球" } ] }; }, mounted() { //進(jìn)入主頁(yè)面自動(dòng)獲取一次表格數(shù)據(jù) this.getData(); }, methods: { //獲取主頁(yè)表格數(shù)據(jù) getData() { axios({ method: "post", url: "/dealData/showData", params: {} }) .then(function(response) { this.tableData = response.data; }) .catch(function(error) { console.log(error); }); }, //獲取編輯頁(yè)面的表格數(shù)據(jù) edit() { this.editDialog = true; //將主表數(shù)據(jù)賦到編輯頁(yè)面的表格數(shù)據(jù)中 this.editData = this.tableData; //循環(huán)獲取表格的每條記錄 for (let i = 0; i < this.editData.length; i++) { //以下代碼的目的是將每條記錄的愛好這一屬性的類型由字符串轉(zhuǎn)換為列表對(duì)象,如替換前為"1,2,3",那么替換后為["1","2","3"] let str = this.editData[i].hobby.split(","); let newArray = []; //循環(huán)獲取每條記錄的愛好集合 for (let j = 0; j < str.length; j++) { newArray.push(str[j]); } this.editData[i].hobby = newArray; } }, //新增記錄時(shí)的保存方法 addSave() { axios({ method: "post", url: "/dealData/addData", params: { 'name': this.formData.name, 'hobby': this.formData.hobby } }) .then(function(response) { console.log(response.data.message); }) .catch(function(error) { console.log(error); }); }, //編輯記錄時(shí)的保存方法 editSave() { var rows = []; var saveData = []; for (let i = 0; i < this.editData.length; i++) { var object = new Object(); //獲取當(dāng)前記錄的所有屬性 rows[i] = this.editData[i]; object.name = rows[i].name; object.hobby = rows[i].hobby; saveData.push(object); } //將數(shù)據(jù)組合成一個(gè)列表對(duì)象(savaData)傳給后端 axios({ method: "post", url: "/dealData/editData", params: savaData }) .then(function(response) { this.$msgbox({ title: "系統(tǒng)提示", message: response.data.message, type: "success" }); }) .catch(function(error) { console.log(error); }); } } } </script> <style scoped> .class1 { margin-top: 50px; margin-bottom: 50px; } .class2 { width: 800px; margin: auto; } .class3 { margin-top: 50px; text-align: center; } </style>
后端:
@Component @Path("/dealData") @Consumes({MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_JSON}) public class DealDataController{ @Path("/showData") @Post public List<personBO> showData (){ //查庫(kù)將數(shù)據(jù)導(dǎo)入表格,personBO類需要自己寫,至少包含id、name、hobby、stringHobby這四個(gè)屬性,其中stringHobby屬性只做前端展示用 List<personBO> personList = DealDataService.getPageData(); for(personBO person: personList){ String hobby = person.getHobby(); //按照愛好編碼依次替換,如替換前為"2,1,3",替換后則為"排球,籃球,足球" String stringHobby = hobby.replace("1","籃球").replace("2","排球").replace("3","足球"); person.setStringHobby(stringHobby) } return personList; } @Path("/addData") @Post public Map<String,String> addData (Map<String, Object> paramMap){ Map<String,String> result = new HashMap<>(); //paramMap對(duì)象的hobby屬性是列表類型,現(xiàn)將其利用逗號(hào)分隔符組合成一個(gè)字符串并賦值給stringHobby,然后存入數(shù)據(jù)庫(kù),例如數(shù)據(jù)庫(kù)表中hobby列看到的數(shù)據(jù)為:"1, 2, 3",表示三種球都是該人的愛好 List<String> hobbyList = (List<String>) paramMap.get("hobby"); paramMap.put("stringHobby", StringUtils.join(hobbyList,',')); //在Dao層將數(shù)據(jù)插入數(shù)據(jù)庫(kù),插入成功返回true,失敗返回false,此方法不展開寫,注意在Mybatis中寫sql語(yǔ)句時(shí)不是存paramMap的hobby的值,而是存paramMap的stringHobby的值 boolean str = DealDataDao.insertData(paramMap); if(str){ result.put("statusCode", "1111"); result.put("message", "數(shù)據(jù)插入成功"); }else{ result.put("statusCode", "0000"); result.put("message", "數(shù)據(jù)插入失敗"); } return result; } @Path("/editData") @Post public Map<String,String> editData (Map<String, List<Map<String,Object>>> paramMap){ Map<String,String> result = new HashMap<>(); //將獲取到的表格數(shù)據(jù)作為對(duì)象列表,一個(gè)對(duì)象對(duì)應(yīng)表格的一條記錄 List<Map<String, Object>> dataList = paramMap.get("saveData"); int seccessNum = 0; //對(duì)表格中的每條記錄進(jìn)行循環(huán)更新 for (Map<String,Object> map: dataList){ //map對(duì)象的hobby屬性是列表類型,現(xiàn)將其利用逗號(hào)分隔符組合成一個(gè)字符串并賦值給stringHobby,然后存入數(shù)據(jù)庫(kù),例如數(shù)據(jù)庫(kù)表中hobby列看到的數(shù)據(jù)為:"1, 2, 3",表示三種球都是該人的愛好 List<String> hobbyList = (List<String>) map.get("hobby"); map.put("stringHobby", StringUtils.join(hobbyList,',')); //在Dao層將數(shù)據(jù)更新至數(shù)據(jù)庫(kù),更新成功返回true,失敗返回false,此方法亦不展開寫,注意在Mybatis中寫sql語(yǔ)句時(shí)不是存map的hobby的值,而是存map的stringHobby的值 boolean str = DealDataDao.updateData(map); if(str) { seccessNum++; } } //判斷更新成功數(shù)是否等于總記錄數(shù) if(seccessNum == dataList.size()){ result.put("statusCode", "1111"); result.put("message", "全部數(shù)據(jù)均更新成功"); }else{ result.put("statusCode", "0000"); result.put("message", "存在更新失敗的記錄"); } return result; }
數(shù)據(jù)庫(kù)表中保存的記錄如下(1代表籃球,2代表排球,3代表足球,屬性hobby為String類型):
id | name | hobby |
1 | 張三 | 3, 1 |
2 | 李四 | 2 |
3 | 王五 | 1, 3, 2 |
到此這篇關(guān)于vue實(shí)現(xiàn)下拉框的多選功能(附后端處理參數(shù))的文章就介紹到這了,更多相關(guān)vue 下拉框多選內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
你知道Vue中神奇的$set是如何實(shí)現(xiàn)的嗎?
在日常開發(fā)中,$set的也是一個(gè)非常實(shí)用的API。但是我們知其然更要知其所以然,接下來(lái)就跟隨小編一起看一下Vue中的$set是如何實(shí)現(xiàn)的吧2022-12-12詳解vue-cli 腳手架項(xiàng)目-package.json
本篇文章主要介紹了詳解vue-cli 腳手架項(xiàng)目-package.json,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-07-07Vue Router根據(jù)后臺(tái)數(shù)據(jù)加載不同的組件實(shí)現(xiàn)
本文主要介紹了根據(jù)用戶所購(gòu)買服務(wù)的不同,有不同的頁(yè)面展現(xiàn)。文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08Vue使用exceljs導(dǎo)出excel文件的詳細(xì)教程
這篇文章主要為大家詳細(xì)介紹了Vue如何使用exceljs導(dǎo)出excel文件的詳細(xì)教程,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2025-03-03學(xué)習(xí)Vue框架中必掌握的重點(diǎn)知識(shí)
這篇文章主要介紹了學(xué)習(xí)Vue中必掌握的重點(diǎn)知識(shí),想了解vue的同學(xué)可以參考下2021-04-04vsCode中vue文件無(wú)法提示html標(biāo)簽的操作方法
在vsCode中書寫Vue頁(yè)面時(shí)無(wú)法提示,那真是很郁悶的事情,下面這篇文章主要給大家介紹了關(guān)于vsCode中vue文件無(wú)法提示html標(biāo)簽的操作方法,需要的朋友可以參考下2023-03-03