用Vue做一个职业选择或地区选择的三级嵌套组件

来源:互联网 发布:mac miller ariana 编辑:程序博客网 时间:2024/06/05 04:27

设计图长这样:
这里写图片描述

如图,大概分为三级。点击事件上有个小trick要注意,那就是,第一级点击后显示第二级,第二级点击之后是toggle第三级。

那个职业选择的数据大概有五千多条,有点多,需要拉接口调。这里写个模拟的,结构就是一级一级套对象,代码如下:

function getJobs__list(level,arg1,arg2){    // 这是展示的    var Jobs__list = {        'worker':{            'coder':{                'shit-coder':'',                'bullshit-coder':''            }        },        'buyer':{            'mbuyer':{                'boybuyer':'',                'dadbuyer':''            },            'wbuyer':{                'girlbuyer':'',            }        },    };    if(level===1){        var _jobs__flist = {}        for(key in Jobs__list){            _jobs__flist[key] = {}        }        return _jobs__flist    };    if(level === 2 && arg1){        return Jobs__list[arg1]    };    if( level === 3 && arg1 && arg2){        console.log(arg1,arg2)        return Jobs__list[arg2][arg1]    }}function getJobSearchResult(searchname){    //这是用于搜索的    var o = {        'algricultrue':{            'fish':{                'fish-buyer':{                    securitylevel:'2',                },                'fisherman':{                    securitylevel:'拒保'                }            }        }    }    o['algricultrue']['fish'][searchname] = {        securitylevel : '1'    }    var results = []    for( key in o){        if(o.hasOwnProperty(key)){            for(key2 in o[key]){                if(o[key].hasOwnProperty(key2)){                    for (key3 in o[key][key2]){                        if(o[key][key2].hasOwnProperty(key3)){                            var s = ''                            s = key + '-' + key2 + '-' + key3                             var so = {}                            so[s]= o[key][key2][key3]['securitylevel']                            results.push(so)                        }                    }                }            }        }    }    return so   }

忽略丑丑的代码吧,这就是个很粗糙的假冒伪劣接口。

这是个组件:

Vue.component('stackedList',{    template:"<article class='stackedlist'>\    <div v-for='(f__value,f__key,f__index) in flist' :class='listkind+\"__flist\"'>\        <header :class='listkind+\"__f\"' @click='showslist(f__key,f__index)'>{{f__key}}</header>\        <article v-show='ssonshow[f__index]' :class='listkind+\"__slist\"' v-for='(s__value,s__key,s__index) of f__value'>\            <header :class='listkind+\"__s\"' @click='showtlist(s__key,f__key,s__index,f__index)'>{{s__key}}</header>\            <article :class='listkind+\"__tlist\"'>\            <p :class='listkind+\"__t\"'  v-for='(t__value,t__key,t__index) of s__value' @click='select(t__key)' v-show='tsonshow[f__index][s__index]'>{{t__key}}</p>\            </article>\        </article>\    </div>\</article>\    ",    props:['listkind','flist'],    data:function() {        return {                    ssonshow:[],            tsonshow:[],        }    },    methods:{        showslist:function(f__key,f__index){            this.$emit('getflist',2,f__key)            this.ssonshow[f__index] = true            this.tsonshow[f__index] = []        },        showtlist:function(s__key,f__key,s__index,f__index){            this.$emit('getslist',3,s__key,f__key)            this.tsonshow[f__index][s__index] = !(!!this.tsonshow[f__index][s__index])        },        select:function(t__key){            this.$emit('passvalue',t__key)        }    }})

组件要套在Jobs组件中(jobs才是那个整体的大组件)

Vue.component('jobs',{    template:"<div class='jobs'><div class='info info__job'>\                <span class='pretip' >职业</span>\                <input type='text' class='answer' v-model='jobselected' placeholder='请选择职业' @click.prevent='togglejobbox(true,$event)'/>\</div>\<div class='jobbox--curtain' v-show='jobboxonshow'>\    <div class='jobbox'>\        <header>\            <p class='jobbox__header'>查询职业类别</p>\            <div class='jobbox__close' @click='togglejobbox(false,$event)'>+</div>\        </header>\        <input class='jobbox__search' type='text' placeholder='搜索职业' @input='showsearchresult' v-model='searchname'/>\        <stacked-list v-show='!searchname.trim()' :listkind='listkind' :flist='flist' @passvalue='selectjob'  @getflist='getflist' @getslist='getslist'></stacked-list>\        <article class='jobbox__searchresult' v-show='searchname.trim()' >\            <p class='jobbox__searchresult__item' v-for='(securitylevel,searchresult) in searchresults'><span class='jobbox__searchresult__item__job'>{{searchresult}}</span><span class='jobbox__searchresult__item__level'>{{securitylevel}}</span></p>\        </article>\    </div>\</div></div>",    props:['jobselected','flist'],    data:function(){        return {            jobboxonshow : false,            searchname:'',            listkind:'jobbox',            searchresults: {}                   }    },    methods:{        togglejobbox:function(ifshow,e){            e.target.blur()            this.jobboxonshow = ifshow ?  true :false ;        },        showsearchresult:function(){            if(!this.searchname){                console.error('no searchname')                return            }            var results =  getJobSearchResult(this.searchname)            this.searchresults = results        },        selectjob:function(jobvalue){            this.$emit('selectjob',jobvalue)            this.jobboxonshow = false        },        getflist: function(level,f__key){            this.$emit('getflist',2,f__key)        },        getslist: function(level,s__key,f__key){            this.$emit('getslist',3,s__key,f__key)        }    }})

然后在主体的VM里挂上< jobs >< / jobs >即可,注意prop哦~

这里其实有多个人都可以选职业,要注意把接口调用的数据返回放在一个vm中,多个组件共用一个性质。或者干脆就一个组件,只是v-model对应不同的人,做个区分就行。然后因为是一级一级查询的,要把数据先缓存在本地,如果Local查不到,再去调接口。