zoukankan      html  css  js  c++  java
  • vue实现下拉框全选和输入匹配

    实际项目中的一个需求:

    点击文本框,弹出带有复选框的选项,然后获取选中项的数据,传给后面的一个功能。在文本框输入内容,也会动态的匹配下拉列表,并且列表带有全选功能。

    朴素的效果图:

     

    我选择了用vue实现,算是vue的一次练手吧。不会写的地方也百度了一下。

    难点有两个,一个是全选。全选不光是点击全选复选框,选项跟着选中或不选中。还包括反向的选择,就是如果把所有选项选中了,那么“全选”也要跟着选中,而有任何一项未选中,那么“全选”则处于未选中状态。也就是说这是个互动的过程。只有做到这点,才是一个好的用户体验。

    我是在循环数据的每一项加了一个表示选中状态的值lineCheck。全选和选项的点击分别写。点击全选中,把选项的状态置为和其一致就可以。

    点击选项时,利用every方法,只有每一项为真(也就是选中),全选才为真,否则为假(未选中)。 

    第二个难点就是输入时的匹配问题,是在computed中写了一个searchLists,下拉列表的for循环也用的这个数据,全选时遍历的也是这个数据。

    其他tips:

    1)表单的操作离不开v-model

    2)点击事件加上stop修饰符,阻止冒泡

    3)复选框的事件用的change

    4)注意用label,这样点击文字也有效果,体验更佳

    5)点击页面空白处,隐藏下拉列表

    总体来说,用户体验做的还是不错的。

    贴出完整代码:(没有好看的样式,就是最朴素的效果,毕竟css对于前端人员来说是最最简单的)

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title>下拉框全选</title>
            <link rel="stylesheet" href="css/this.css" />
        </head>
        <body>
            <div class="m-select-wrap" id="v_app">
                <div class="title">
                    <input type="text" placeholder="输入/勾选" v-model="searchLine" @click.stop="showList" @focus="inputFocus">
                    <span class="show-list" @click.stop="toggleList"></span>
                    <span class="select-con">选中了:{{selectCon}}</span>
                </div>
                <ul v-if="isShow" @click.stop="showList">
                    <li>
                        <label><input type="checkbox" v-model="checkAllState" @change="checkAll"> 全选</label>
                    </li>
                    <li v-for="item in searchLists">
                        <label :id="item.lineId"><input type="checkbox" v-model="item.lineCheck" @change="checkOne(item)"> {{item.lineName}}</label>
                    </li>
                </ul>
            </div>
    
            <script src="js/vue.js"></script>
            <script>
                var lines = [
                    {
                        lineId: 'line1',
                        lineName: '数据1',
                        lineCheck: false
                    },
                    {
                        lineId: 'line2',
                        lineName: '数据2',
                        lineCheck: false
                    },
                    {
                        lineId: 'line3',
                        lineName: '数据3',
                        lineCheck: false
                    },
                    {
                        lineId: 'line4',
                        lineName: '数据4',
                        lineCheck: false
                    },
                    {
                        lineId: 'line5',
                        lineName: '数据5',
                        lineCheck: false
                    }                
                ]
    
                new Vue({
                    el: '#v_app',
                    data: {
                        //数据
                        lineList: lines,
                        //选项的选中状态
                        checkAllState: false,
                        //选中的数据
                        checkedList: [],
                        //文本框的值
                        searchLine: '',
                        //下拉列表是否显示
                        isShow:false,
                        //选中的内容
                        selectCon:''
                    },
                    methods: {
                        //全选
                        checkAll: function() {
                            for (var i = 0; i < this.searchLists.length; i++) {
                                this.searchLists[i].lineCheck = this.checkAllState;
                            }                        
                            this.getCheckData();
                        },
                        //选择单个
                        checkOne: function(item) {
                            this.searchLists.every(function(item) {
                                return item.lineCheck == true;
                            }) ? this.checkAllState = true : this.checkAllState = false;                        
                            this.getCheckData();                        
                        },
                        //获取选中的数据
                        getCheckData: function() {
                            this.checkedList = this.searchLists.filter(function(item) {
                                return item.lineCheck == true;
                            })
                            
                            //选中的值显示到输入框中
                            this.selectCon='';
                            for(var i=0;i<this.checkedList.length;i++){
                                this.selectCon+=this.checkedList[i].lineName+',';
                            }                
                        },
                        //切换下拉列表
                        toggleList:function(){
                            this.isShow=!this.isShow;                        
                        },
                        //显示下拉列表
                        showList:function(){
                            this.isShow=true;                        
                        },
                        //文本框获得焦点时文字被选中
                        inputFocus:function(e){
                            e.currentTarget.select();
                        }                    
                    },
                    computed: {
                        //输入框筛选列表
                        searchLists: function() {
                            var _search = this.searchLine;
                            if (_search) {
                                return this.lineList.filter(function(item) {
                                    return Object.keys(item).some(function(key) {
                                        return String(item.lineName).toLowerCase().indexOf(_search) > -1
                                    })
                                })
                            }
                            return this.lineList;
                        }
                    },                
                    mounted:function(){
                        var _this=this;
                        //点击页面空白处隐藏下拉列表
                        document.addEventListener('click',function(){                        
                            _this.isShow=false;
                        });
                    }
                });
            </script>
        </body>
    </html>

    css:

    .m-select-wrap{width: 300px;margin: 20px auto 0;}
    .m-select-wrap .title{width: 300px;position: relative;}
    .m-select-wrap input[type="text"]{width: 300px;height: 40px;padding: 0 5px;}
    .m-select-wrap .select-con{position: absolute;left: 105%;white-space: nowrap;line-height: 40px;}
    .m-select-wrap .show-list{position: absolute; width: 30px;height: 40px;line-height: 38px;border: 1px solid #aaa;right: 0;text-align: center;cursor: pointer;}
    .m-select-wrap ul{border: 1px solid #ccc;padding:0 30px 10px 10px;}
    .m-select-wrap li{margin-top: 10px;}
  • 相关阅读:
    Codeforces Round #600 (Div. 2) A. Single Push
    Codeforces Round #600 (Div. 2) B. Silly Mistake
    106. 从中序与后序遍历序列构造二叉树
    23. 合并K个升序链表
    203. 移除链表元素
    328. 奇偶链表
    86. 分隔链表
    面试题 02.05. 链表求和
    面试题 02.02. 返回倒数第 k 个节点
    剑指 Offer 18. 删除链表的节点
  • 原文地址:https://www.cnblogs.com/hzhjxx/p/12145218.html
Copyright © 2011-2022 走看看