vue实现下拉框的多选功能(附后端处理参数)

 更新时间:2023年08月08日 10:19:51   作者:【金融科技蚂蚁】  
本文介绍了如何使用Vue实现下拉框的多选功能,实现了在选择框中选择多个选项的功能,文章详细介绍了实现步骤和示例代码,对于想要了解如何使用Vue实现下拉框多选功能的读者具有一定的参考价值

本次演示共涉及三个界面,一个是主表用于展示数据的,一个是表单用于新增数据的,另一个则是编辑用于修改表格数据的,先上效果图:

1、主表界面(数据来源于数据库查表返回):

<el-table :data="tableData" border>
    <el-table-column type="index" label="序号"></el-table-column>
    <el-table-column label="姓名" prop="name"></el-table-column>
    <el-table-column label="爱好" prop="stringHobby"></el-table-column>
</el-table>

2、新增数据界面(点击新增按钮触发):

如果要实现对“爱好”这一属性进行下拉框多选,那么前端核心代码可这么写:

//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: "足球" }
            ]
        }
    }
}

如上图所示,你选择了篮球和排球,那么篮球和排球所对应的码值“1”和“2”就会存入hobby这个属性中,此时formData.hobby的类型是一个列表,其值为["1", "2"],这个值是要作为参数传到后台作处理的。

3、编辑数据界面(点击编辑按钮触发):

编辑界面要实现下拉框多选功能,和新增界面是类似的,但难点有两点:1、当点击上方的编辑按钮时,如何将主表界面的数据全部且正确地带过去?此时编辑界面的表格数据要和主表界面的数据完全一致并且“爱好”这一列自动选择好,用户可直接在现有的数据上作编辑而不是进去后"爱好"这一列都是空的;2、编辑好后整个表格数据的保存问题会比新增要复杂,这些字段在前端如何处理才能被后台接收且方便保存?

针对难点一,我们会想到将主表中:data="tableData"的tableData赋值给这个编辑表格的:data,但是这样只能将“姓名”带过去,因为这个属性在两个界面都是字符串类型直接映射就好,“爱好”属性则不同,它在主表是字符串,到了编辑表必须转换为字符列表才行。如张三的爱好是足球和篮球,在主表中属性值为"3, 1"(字符串类型),需要转为["3", "1"](字符列表类型),这样系统才能根据你设置的hobbyList中的value-label进行自动匹配,核心代码如下:

//html部分
<el-dialog title="编辑" :visible.sync="editDialog">
    <el-table :data="editData" border>
        <el-table-column type="index" label="序号"></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: {
        //获取编辑页面的表格数据
        edit() {
            this.editDialog = true;
            //将主表数据赋到编辑页面的表格数据中
            this.editData = this.tableData;
            //循环获取表格的每条记录
            for (let i = 0; i < this.editData.length; i++) {
            //以下代码的目的是将每条记录的爱好这一属性的类型由字符串转换为列表对象,如替换前为"1,2,3",那么替换后为["1","2","3"]
                let str = this.editData[i].hobby.split(",");
                let newArray = [];
                //循环获取每条记录的爱好集合
                for (let j = 0; j < str.length; j++) {
                    newArray.push(str[j]);
                }
                this.editData[i].hobby = newArray;
            }
        }
    }
}

针对难点二,实现方法就是对表格的每条记录都要处理一下(主要是处理"爱好"这一列),然后做循环逐条存库,此处没必要长篇大论,直接上代码:

//html部分
<el-button @click="editSave" icon="el-icon-edit">
    保存
</el-button>
//js部分
export default {
    methods: {
        //编辑记录时的保存方法
        editSave() {
            var rows=[]
            var saveData=[]
            for(let i=0; i< this.editData.length; i++){
                var object = new Object()
                //获取当前记录的所有属性
                rows[i] = this.editData[i]
                object.name = rows[i].name
                object.hobby = rows[i].hobby
                saveData.push(object)
            }
            //将数据组合成一个列表对象(savaData)传给后端
            axios({
                method: "post",
                url: "/dealData/editData",
                params: savaData
            })
            .then(function(response) {
                this.$msgbox({
                    title: '系统提示',
                    message: response.data.message,
                    type: 'success',
                })
            })
            .catch(function(error) {
                console.log(error)
            })
        }
    }
}

以下是完整的前后端代码,可拿来直接运行:

前端:

<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="序号" 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="序号"></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() {
        //进入主页面自动获取一次表格数据
        this.getData();
    },
    methods: {
        //获取主页表格数据
        getData() {
            axios({
                method: "post",
                url: "/dealData/showData",
                params: {}
            })
            .then(function(response) {
                this.tableData = response.data;
            })
            .catch(function(error) {
                console.log(error);
            });
        },
        //获取编辑页面的表格数据
        edit() {
            this.editDialog = true;
            //将主表数据赋到编辑页面的表格数据中
            this.editData = this.tableData;
            //循环获取表格的每条记录
            for (let i = 0; i < this.editData.length; i++) {
                //以下代码的目的是将每条记录的爱好这一属性的类型由字符串转换为列表对象,如替换前为"1,2,3",那么替换后为["1","2","3"]
                let str = this.editData[i].hobby.split(",");
                let newArray = [];
                //循环获取每条记录的爱好集合
                for (let j = 0; j < str.length; j++) {
                    newArray.push(str[j]);
                }
                this.editData[i].hobby = newArray;
            }
        },
        //新增记录时的保存方法
        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);
            });
        },
        //编辑记录时的保存方法
        editSave() {
            var rows = [];
            var saveData = [];
            for (let i = 0; i < this.editData.length; i++) {
                var object = new Object();
                //获取当前记录的所有属性
                rows[i] = this.editData[i];
                object.name = rows[i].name;
                object.hobby = rows[i].hobby;
                saveData.push(object);
            }
            //将数据组合成一个列表对象(savaData)传给后端
            axios({
                method: "post",
                url: "/dealData/editData",
                params: savaData
            })
            .then(function(response) {
                this.$msgbox({
                    title: "系统提示",
                    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 (){
        //查库将数据导入表格,personBO类需要自己写,至少包含id、name、hobby、stringHobby这四个属性,其中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对象的hobby属性是列表类型,现将其利用逗号分隔符组合成一个字符串并赋值给stringHobby,然后存入数据库,例如数据库表中hobby列看到的数据为:"1, 2, 3",表示三种球都是该人的爱好
        List<String> hobbyList = (List<String>) paramMap.get("hobby");
        paramMap.put("stringHobby", StringUtils.join(hobbyList,','));
        //在Dao层将数据插入数据库,插入成功返回true,失败返回false,此方法不展开写,注意在Mybatis中写sql语句时不是存paramMap的hobby的值,而是存paramMap的stringHobby的值
        boolean str = DealDataDao.insertData(paramMap);
        if(str){
            result.put("statusCode", "1111");
            result.put("message", "数据插入成功");
        }else{
            result.put("statusCode", "0000");
            result.put("message", "数据插入失败");
        }
        return result;
    }
    @Path("/editData")
    @Post
    public Map<String,String> editData (Map<String, List<Map<String,Object>>> paramMap){
        Map<String,String> result = new HashMap<>();
        //将获取到的表格数据作为对象列表,一个对象对应表格的一条记录
        List<Map<String, Object>> dataList = paramMap.get("saveData");
        int seccessNum = 0;
        //对表格中的每条记录进行循环更新
        for (Map<String,Object> map: dataList){
        //map对象的hobby属性是列表类型,现将其利用逗号分隔符组合成一个字符串并赋值给stringHobby,然后存入数据库,例如数据库表中hobby列看到的数据为:"1, 2, 3",表示三种球都是该人的爱好
            List<String> hobbyList = (List<String>) map.get("hobby");
            map.put("stringHobby", StringUtils.join(hobbyList,','));
            //在Dao层将数据更新至数据库,更新成功返回true,失败返回false,此方法亦不展开写,注意在Mybatis中写sql语句时不是存map的hobby的值,而是存map的stringHobby的值
            boolean str = DealDataDao.updateData(map);
            if(str) {
                seccessNum++;         
            }
        }
        //判断更新成功数是否等于总记录数
        if(seccessNum == dataList.size()){
            result.put("statusCode", "1111");
            result.put("message", "全部数据均更新成功");
        }else{
            result.put("statusCode", "0000");
            result.put("message", "存在更新失败的记录");
        }
        return result;
    }

数据库表中保存的记录如下(1代表篮球,2代表排球,3代表足球,属性hobby为String类型):

idnamehobby
1张三3, 1
2李四2
3王五1, 3, 2

 到此这篇关于vue实现下拉框的多选功能(附后端处理参数)的文章就介绍到这了,更多相关vue 下拉框多选内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Vue Computed底层原理深入探究

    Vue Computed底层原理深入探究

    computed是vue的配置选项,它的值是一个对象,其中可定义多个计算属性,每个计算属性就是一个函数,下面这篇文章主要给大家介绍了关于vue中计算属性computed的详细讲解,需要的朋友可以参考下
    2022-08-08
  • VUE中对object.object和object[object]的使用解读

    VUE中对object.object和object[object]的使用解读

    这篇文章主要介绍了VUE中对object.object和object[object]的使用,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-06-06
  • vue更改数组中的值实例代码详解

    vue更改数组中的值实例代码详解

    这篇文章主要介绍了vue更改数组中的值,本文通过两个例子,给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-02-02
  • vue手写加载动画项目

    vue手写加载动画项目

    这篇文章主要为大家详细介绍了vue手写加载动画项目,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • 用了这么久的Vue3你真的了解Proxy了吗

    用了这么久的Vue3你真的了解Proxy了吗

    Proxy是ES6引入的一个新特性,它允许你创建一个代理对象,用于拦截对目标对象的访问,但用了这么久的vue3,你真的懂Proxy吗,本文就来和大家深入聊聊Proxy吧
    2023-06-06
  • Vue项目部署到IIS后刷新报错404的问题及解决方法

    Vue项目部署到IIS后刷新报错404的问题及解决方法

    这篇文章主要介绍了Vue项目部署到IIS后,刷新报错404,这里需要用到URL重写工具 --URL Rewrite,需要的话需要自己下载安装,本文通过图文并茂的形式给大家介绍的非常详细,需要的朋友可以参考下
    2022-10-10
  • Vue3源码分析调度器与watch用法原理

    Vue3源码分析调度器与watch用法原理

    这篇文章主要为大家介绍了Vue3源码分析调度器与watch用法原理详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-01-01
  • VUE中路由变化this.$router(push\replace\go\back)解读

    VUE中路由变化this.$router(push\replace\go\back)解读

    这篇文章主要介绍了VUE中路由变化this.$router(push\replace\go\back),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-10-10
  • element表格组件实现右键菜单的功能

    element表格组件实现右键菜单的功能

    本文主要介绍了element表格组件实现右键菜单的功能,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • vue项目及axios请求获取数据方式

    vue项目及axios请求获取数据方式

    这篇文章主要介绍了vue项目及axios请求获取数据方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08

最新评论