zoukankan      html  css  js  c++  java
  • 完成iview的下拉select既可以编辑内容又可以选择下拉选项的功能(借助iview的自动完成组件)

    最近在使用iview重构老项目页面代码的时候,发现老项目有部分下拉框既可以编辑又可以选择下拉框自带的内容,找了找iview的select组件,发现并没有一个类似的功能。

    最接近我的需求的,可能是设置select的filterable属性开启搜索模式,但是每次输入新的内容,鼠标一离开不是被清空,就是选中之前选择的一项,故放弃。

    后来又看到iview4.0的版本加了一个allow-create属性,拿给老大看了下,他觉得太麻烦了,不够简洁,首先是必须输完自定义的内容后,一定要点下图的箭头或者按回车,才能将内容加到列表。

    另外就是觉得一定要把自定义的内容加到列表中,总觉得不舒服(不是我觉得啊),因此放弃。

     对select抱有一丝希望的试了试,出了很多问题,最后放弃了用select组件来做。

    后边使用select也实现了该功能,可以查看我下一篇随笔: https://www.cnblogs.com/mayiaction/p/12066923.html

    后边发现 auto-complete 组件很简洁,在其基础上做了一些改动,最终完成了这个要求,由于考虑到了模糊查询的功能,由于做法的限制,抛弃了iview该组件自带的模糊搜索,所以代码复杂了点。

    代码如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <link rel="stylesheet" type="text/css" href="http://unpkg.com/iview/dist/styles/iview.css">
        <script type="text/javascript" src="http://vuejs.org/js/vue.min.js"></script>
        <script type="text/javascript" src="http://unpkg.com/iview/dist/iview.min.js"></script>
        <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
        <style type="text/css">
            #app{padding: 32px;}
            [myfocus]{
                color: #2d8cf0;
                background: #f3f3f3;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <auto-complete
                ref = "test"
                v-model="nowLabel"
                @on-change="changeSel"
                @on-select="selectSel"
                style="200px" icon="ios-arrow-down" >
    
                <i-Option v-for="option in selArr" :value="option.label+'|'+option.value" :key="option.value" >
                    <span >{{option.label}}</span>
                </i-Option>
            </auto-complete>
        </div>
    </body>
    <script type="text/javascript">
        window.vm = new Vue({
            el: '#app',
            data: {
                nowLabel: '',    //存储输入框中显示的内容
                nowSel: undefined,    //存储需要提交给后台的value
                lastLabel: '',    //存储上一次输入的内容
                selArr:[],    //存储select下拉框绑定的列表
                isSel:false, ////由于选中和输入内容都会触发onchange,设置此变量进行区分两种情况
                //存储页面的原始列表
                prevArr:[
                    {
                        value:'n',
                        label:'NewYork'
                    },
                    {
                        value:'l',
                        label:'London'
                    },
                    {
                        value:'s',
                        label:'Sydney'
                    },
                    {
                        value:'o',
                        label:'Ottawa'
                    },
                    {
                        value:'p',
                        label:'Paris'
                    },
                    {
                        value: 'c',
                        label: 'Canberra'
                    }
                ]
    
            },
            created:function(){
                this.selArr = this.prevArr;    //页面初次加载,下拉列表就是原始列表
            },
            methods: {
                filterMethod:function(value,arr) {
                    var newArr = [];
                    for(var i=0;i<arr.length;i++){
                        if(arr[i].label.toUpperCase().indexOf(value.toUpperCase()) !== -1){
                            //模糊查询到了,塞入新数组
                            newArr.push(arr[i]);
                        }
                    }
                    this.selArr = newArr;
                },
                changeSel:function(){
                    //更改事件
                    var that = this;
                    if(that.isSel){
                        //如果输入框的改变是选中内容引发的,就什么也不做,同时重新初始化标识,为了解决选中同一内容两次引发的bug
                        that.isSel = false;
                        return false;
                    }
                    
                    var input = that.nowLabel;    //获取输入框输入的内容
                    that.nowSel = input;
                    that.clearSelCss(that,"test");
    
     
                    //将输入内容与上一次的输入内容比对上一次输入内容,判断是到初始化列表中查还是从上次查询结果列表查
                    if(input == null || input == undefined || input == ""){
                        //输入内容是空,显示原始列表
                        that.selArr = that.prevArr;
                    }else if(input.indexOf(that.lastLabel)==0){
                        //此次输入内容是上次输入内容的开头,不需要到原始列表查,只要到上次查询结果中查
                        that.filterMethod(input,that.selArr);
                    }else{
                        //其他情况到原始列表中查
                        that.filterMethod(input,that.prevArr);
                    }
                    this.lastLabel = input;     
                },
                selectSel:function(val){
                    let that = this;
                    //选中事件
                    that.isSel = true;
                    var label = val.split("|")[0];
                    that.nowSel = val.split("|")[1];
                    Vue.nextTick(function () {
                        that.nowLabel = label;
    
                        that.clearSelCss(that,"test");
                        var focusItem = $(that.$refs.test.$el).find(".ivu-select-item-focus");
                        //定义一个属性,用于给选中项设置样式,之所以不设置class,是因为iview会将class替换掉
                        focusItem.attr("myfocus","myfocus");
                    });
                },
    
                clearSelCss:function(that,ref){
                    //清除掉已经被选中的项的css
                    var lastSel = $(that.$refs[ref].$el).find("[myfocus]");
                    lastSel.removeAttr("myfocus");
                }
            }
        })
                            
    </script>
    </html>

    效果如下,当选中了列表中的内容的时候,需要提交给后台的是选中项的value,而不是label

    当自己输入内容的时候,由于并不确定value的值,就认为输入框中的内容就是value,效果如下:

     如果有什么疑问,欢迎留言!

  • 相关阅读:
    java中的socket编程有关printStream的println方法和write方法
    json在php中的用法
    js的数组处理函数splice
    将博客搬至CSDN
    mapreduce导出MSSQL的数据到HDFS
    基于信息熵的无字典分词算法
    搜索引擎手记(三)之网页的去重
    算法之常用的距离和相似度度量
    搜索引擎手记(二)之爬虫的开发
    搜索引擎手记(一)之引擎工作的开始
  • 原文地址:https://www.cnblogs.com/mayiaction/p/12030504.html
Copyright © 2011-2022 走看看