【前端】带多过滤条件的穿梭框

不会写前端的后端程序员不是好厨子。

一直写后端久了,前端的技术能力一直没有提升上去。

最近有这样一个需求,要求做大屏数据的配置页面,用户在配置页面勾选指定的资源,然后在大屏页面即可看到指定资源的相关信息。并且要求针对资源够搜索的功能。

我直接找了一个老页面,copy了一个dialog的带复选框的表格放了上去,大体效果如下

并且实现了,当选中5条数据的时候,禁止再勾选其他的资源,看起来一切都是那么美好,直到我使用过滤之后,发现灾难开始了。

  1. 在页面上勾选了5条,然后点击下拉框或者文本框输入内容,发现之前禁止勾选的复选框又可以勾选了。
  2. 在有过滤条件的情况下,勾选资源,然后清除过滤条件,发现之前勾选的资源没了,变成不勾选了。

类似的BUG,数不胜数,改了这个出现那个。后来就想到了使用elementUI的穿梭框来解决这个问题,但是穿梭框没有针对多个属性过滤的功能,于是就写了两个并排的表格去完成这个功能。至此才解决了这个令人头疼的BUG。

最终呈现的效果如下

勾选过的资源放到右边,未勾选的资源放到左边,然后左边的资源可以进行搜索,每次搜索的时候左侧的列表会跟着过滤,不会影响右侧勾选的资源。

先将部分代码展示如下,以便于后续使用。

js 复制代码
 <el-dialog :title="$t('formInfo.selectingPorts')" :visible.sync="selectingPortDialogVisible" top="10vh" width="80%"
               @close="closeApiDialog" >
        <el-row class="dialog">

            <el-col span="24">
                <el-select @change="inputContextChange" filterable v-model="selectedResIds" multiple
                           placeholder="请选择资源IP"
                           style=" width: 300px;" size="mini">

                    <el-option
                            v-for="item in selectingResources"
                            :key="item"
                            :label="item"
                            :value="item">
                    </el-option>


                </el-select>
                <el-input class="ioco" :placeholder="$t('inputPortName')" prefix-icon="el-icon-search"
                          v-model="inputContext"
                          style="width:200px" @input="inputContextChange" size="mini">
                </el-input>
            </el-col>

            <el-col span="24">
                <div>
                    <el-table style="width: 45%; float: left;margin-top:20px" :data="portData" border height="400"
                              ref="multipleTablePort"
                    >
                        <el-table-column prop="portName" :label="$t('colums.portName')" sortable
                                         show-overflow-tooltip=true>
                        </el-table-column>
                        <el-table-column prop="resourceIp" label="IP" show-overflow-tooltip=true></el-table-column>
                        <el-table-column prop="resourceName" :label="$t('colums.resourceName')"
                                         show-overflow-tooltip=true></el-table-column>
                        <el-table-column
                                label="操作">
                            <template slot-scope="scope">
                                <el-button :disabled="isAdd" type="text" @click="moveToTarget(scope.row,'switch')">添加
                                </el-button>
                            </template>
                        </el-table-column>
                    </el-table>

                    <el-table style="margin-left:10vh;width: 45%; float: left;margin-top:20px" :data="selection" border
                              height="400"
                              ref="multipleTablePort"
                    >
                        <el-table-column prop="portName" :label="$t('colums.portName')" sortable
                                         show-overflow-tooltip=true :min-width="100">
                        </el-table-column>
                        <el-table-column prop="resourceIp" label="IP" show-overflow-tooltip=true></el-table-column>
                        <el-table-column prop="resourceName" :label="$t('colums.resourceName')"
                                         show-overflow-tooltip=true></el-table-column>
                        <el-table-column
                                label="操作">
                            <template slot-scope="scope">
                                <el-button type="text" @click="moveToSource(scope.row,'switch')">移除</el-button>
                            </template>
                        </el-table-column>
                    </el-table>

                </div>
                </template>
            </el-col>
        </el-row>

        <div style="text-align:center;margin-top:10px;margin-bottom:10px">
            <el-butto class="btn btn-self" @click="addSelectingApi">{{$t('button.sure')}}</el-butto>
            <el-butto class="btn btn-self" @click="closeApiDialog">{{$t('button.cancel')}}</el-butto>
        </div>
    </el-dialog>
js 复制代码
  moveToTarget(row,type) {
                       if(type==="host"){
                           const index = this.apiData.indexOf(row);
                           if (index !== -1) {
                               this.apiData.splice(index, 1);
                               this.selection.push(row);
                           }
                           if (this.selection.length >= 5) {
                               this.isAdd = true
                               //todo
                               this.$message.warning(`当前已经选${this.checkNumber}条,不可再多选`);
                           } else {
                               this.isAdd = false
                           }
                       }else {
                           const index = this.portData.indexOf(row);
                           if (index !== -1) {
                               this.portData.splice(index, 1);
                               this.selection.push(row);
                           }
                           if (this.selection.length >= 5) {
                               this.isAdd = true
                               this.$message.warning(`当前已经选${this.checkNumber}条,不可再多选`);
                           } else {
                               this.isAdd = false
                           }
                       }
                    },
                    moveToSource(row,type) {
                       if(type==='switch'){
                           const index = this.selection.indexOf(row);
                           if (index !== -1) {
                               this.selection.splice(index, 1);
                               this.portData.push(row);
                           }
                           if (this.selection.length < 5) {
                               this.isAdd = false
                           }
                       }else {
                           const index = this.selection.indexOf(row);
                           if (index !== -1) {
                               this.selection.splice(index, 1);
                               this.apiData.push(row);
                           }
                           if (this.selection.length < 5) {
                               this.isAdd = false
                           }
                       }
                    },

以后再遇到此类场景需要想到使用多种组件,不能一个表格傻乎乎用到死。

相关推荐
风铃喵游3 分钟前
构建引擎: 打造小程序编译器
前端·小程序·架构
sunbyte8 分钟前
50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | ThemeClock(主题时钟)
前端·javascript·css·vue.js·前端框架·tailwindcss
小飞悟17 分钟前
🎯 什么是模块化?CommonJS 和 ES6 Modules 到底有什么区别?小白也能看懂
前端·javascript·设计
浏览器API调用工程师_Taylor17 分钟前
AOP魔法:一招实现登录弹窗的全局拦截与动态处理
前端·javascript·vue.js
FogLetter18 分钟前
初识图片懒加载:让网页像"懒人"一样聪明加载
前端·javascript
微客鸟窝19 分钟前
一文搞懂NVM管理Node.js:从安装到实战全攻略
前端
归于尽20 分钟前
Cookie、Session、JWT 的前世今生
前端
程序员辉哥21 分钟前
学会在Cursor中使用Rules生成代码后可以躺平了吗?
前端·后端
请你吃div26 分钟前
JavaScript 实用函数大全(超实用)
前端·javascript·面试
一个水瓶座程序猿.27 分钟前
Vue3 中使用 Vueuse
前端·javascript·vue.js