Front end-"Element grouping + search + fuzzy matching multi-select drop-down box in vue

First on the renderings:

This function is actually not difficult to implement, there are mainly several details that need attention

1. Export of js module in vue

2. The use of linq

3. Business logic processing of primary and secondary grouping

The main implementation steps are as follows:

One: prepare linq

1. Install linq.

npm install linq

2. Reference in main.js

import linq from 'linq';
Vue.prototype.Enumerable=linq;

3. Understanding of linq. I personally feel that it is more similar to the stream operation in Java8, and the specific use can be Baidu.

Recommend a summary: https://blog.csdn.net/jsjpanxiaoyu/article/details/76560182

Two: template page

<el-form-item v-if="editDailogFormType=='region'" label="需求省份" prop="channelName">
                    <el-select v-model="regionConfigForm.citys" placeholder="请选择区域"
                               multiple
                               filterable
                               remote
                               reserve-keyword
                               :remote-method="(queryString)=>{remoteMethod(queryString);}"
                               style="width: 100%;">
                        <el-option-group
                                v-for="group in multipleSelectOption"
                                :key="group.province"
                                :label="group.province"
                                @click.native="checkProvince(group.province)">
                            <el-option
                                    v-for="item in group.city"
                                    :key="item.value"
                                    :label="item.city_name"
                                    :value="item.city_name">
                            </el-option>
                        </el-option-group>
                    </el-select>
</el-form-item>

 

 Superfluously explain these attributes of the el-select drop-down box

multipe: open multiple selection

filterable: open search

remote: open remote search

reserve-keyword: keyword

:Remote-method: The method of remote search trigger.

 

The el-option-group under el-select is the group name (such as province), and el-option is the specific option under the group (such as city).

@click.native is the method that is triggered when the group name is clicked.

three:

1. Preparation of json data. My json format is [{province:xxx,city:[{city_name:xxx}]}]. Below is the link, you can download it if necessary

https://download.csdn.net/download/nienianzhi1744/12084829

Since provinces and cities are static resources, I can make a json file. If it is a dynamic resource, I can request a background interface to get data from the background.

2. Pinyin related js.

The commonly used js methods are written below. If you are careful, you may have found that the pinyin global variable in the code below only defines one pinyin. This pinyin variable is a string in json format, which is too long and takes up too much space and affects reading. I put it in my download, and can download it if necessary.

https://download.csdn.net/download/nienianzhi1744/12084844

Contains the conversion of Chinese characters to pinyin, the extraction of the first spell, the comparison and inclusion methods of Chinese characters, the whole pin, and the first pin.

Specific operation: Create a js file named pinYinForVue. Copy the following content

export const pinyin = {
    'a': '\u554a\u963f\u9515',
}
export default {

    arraySearch: function (l1, l2) {
        for (let name in pinyin) {
            if (pinyin[name].indexOf(l1) !== -1) {
                return this.ucfirst(name)
            }
        }
        return false
    },
    ucfirst: function (l1) {
        if (l1.length > 0) {
            let first = l1.substr(0, 1).toUpperCase();
            let spare = l1.substr(1, l1.length);
            return first + spare
        }
    },
    /*获取首字母*/
    getInitials: function (text) {
        let pinyin="";
        for (let i = 0; i < text.length; i++) {
            pinyin=pinyin+this.convertToPinYin(text[i])[0];
        }
        return pinyin; //若取拼音,则返回 pinyin
    },

    /*判断text中是否包含key,通过汉字、拼音、首拼判断*/
    wordInclude:function (text,key) {
        if(this.convertToPinYin(text).toLowerCase().indexOf(key) != -1||//全拼是否包含
            this.convertToPinYin(text).indexOf(key) != -1 ||//全拼转小写是否包含
            this.getInitials(text).toLowerCase().indexOf(key) != -1||//首拼是否包含
            this.getInitials(text).indexOf(key) != -1 ||//首拼转小写是否包含
            text.indexOf(key) != -1 //汉字是否包含
        ){
           return true;
        }else{
            return false;
        }
    },
    /*这个转拼音的方法可以单独拿出去用(更灵活),也可以在下方的wordInclude中被调用*/
    convertToPinYin: function (l1) {
        let l2 = l1.length;
        let I1 = '';
        let reg = new RegExp('[a-zA-Z0-9]');
        for (let i = 0; i < l2; i++) {
            let val = l1.substr(i, 1);
            let name = this.arraySearch(val, pinyin);
            if (reg.test(val)) {
                I1 += val
            } else if (name !== false) {
                I1 += name
            }
        }
        I1 = I1.replace(/ /g, '-');
        while (I1.indexOf('--') > 0) {
            I1 = I1.replace('--', '-')
        }
        return I1
    },
} 

3. Call

这个注释是我写的最详细的一次
import pinyin  from '../../utils/pinYinForVue'
import cityjson from '../../assets/city'

export default {
   data(){
        return {
            regionConfigForm:{
                    citys:[]
            }
            multipleSelectOption:cityjson,
        }
   },
   methods: {
        remoteMethod(queryString) {
                /*json中的一级分组是省份,二级分组是城市*/
                this.multipleSelectOption=cityjson;
                /*去掉重复key,linq中的distinct,where,select 类似Java8的stream流操作*/
                this.multipleSelectOption=this.Enumerable.from(this.multipleSelectOption).distinct("o=>o.province").toArray();
                /*遍历所有省份数据,根据输入框中的值对所有的一级分组过滤,保留符合条件的数据再重新组装成list*/
                let parentSearchList=this.Enumerable.from(this.multipleSelectOption).where((data)=>{
                    let jsonHasQueryString=false;
                    /*如果省份的汉字、全拼、首拼是否包含输入的值*/
                    if(pinyin.wordInclude(data.province,queryString)){
                        jsonHasQueryString=true;
                    }
                    return jsonHasQueryString;
                }).toArray();

                let childSearchList=[];
                /*遍历所有城市数据,根据json数据结构先遍历省份,再遍历省份下城市。*/
                for(let i=0;i<this.multipleSelectOption.length;i++){
                    let parentItem=this.multipleSelectOption[i];
                    for(let j=0;j<parentItem.city.length;j++){
                        let childName=parentItem.city[j].city_name;
                        /*如果城市的汉字、全拼、首拼是否包含输入的值*/
                        if(pinyin.wordInclude(childName,queryString)){
                            childSearchList.push({province:parentItem.province,city:[{city_name:childName}]});
                        }
                    }
                }
                /*合并一级分组和二级分组的值,比如 输入 “hb”,
                会出现一级分组“河北”及下属的多个二级城市,也会出现 单独的二级分组“淮北”以及所属的一级省份“安徽”*/
                let nowmultipleSelectOption =parentSearchList.concat(childSearchList);
                /*去掉key相同的重复数据,key相同虽然不影响使用,但控制台会报红*/
                this.multipleSelectOption = this.Enumerable.from(nowmultipleSelectOption).distinct("o=>o.province").toArray();
            },
            /*一级分组名点击全选*/
            checkProvince(province){
                /*定义一个临时数组*/
                let addProvinceCitys= [];
                /*这个for循环是为了实现点击一级分组全部勾选的功能*/
                for(let i=0;i<cityjson.length;i++){
                    /*遍历所有省份*/
                    let parentItem=cityjson[i];
                    if(parentItem.province==province){
                        /*若省份能跟此次点击的省份匹配,遍历城市*/
                        for(let j=0;j<parentItem.city.length;j++){
                            /*获取已选中元素中是否包含 此次省份下的城市,如果不包含则添加到临时数组中*/
                            let childName=parentItem.city[j].city_name;
                            let index=this.regionConfigForm.citys.indexOf(childName);
                            if(index==-1){
                                addProvinceCitys.push(childName);
                            }
                        }
                    }
                }
                /*其实还想做一个反选功能的,但思路暂时还没捋顺,以后再补充*/
                /*将临时数组中合并到下拉框的已选择数组中,即可完成赋值选中*/
                this.regionConfigForm.citys = this.regionConfigForm.citys.concat(addProvinceCitys);
            },
   }
}

over。

happy New Year

Guess you like

Origin blog.csdn.net/nienianzhi1744/article/details/103860554