vue+mint-ui 移动端框架Picker 组件实现 省市区 三级联动

移动端实现三级联动

mint-ui api传送门 官网链接
npm 安装

npm i mint-ui -S

引入 Mint UI 分两种形式:
一是完全引入,具体实现方式 在 main.js 写入以下代码:
重要:样式文件需要单独引入

import Vue from 'vue'
import MintUI from 'mint-ui'
import 'mint-ui/lib/style.css'
import App from './App.vue'

Vue.use(MintUI)

new Vue({
  el: '#app',
  components: { App }
})

二是按需引入:
以Toast, Picker,Field组件为例,vue组件注入

//main.js:
import Vue from 'vue'
import App from './App.vue'
import { Toast, Picker,Field} from 'mint-ui';
Vue.prototype.$toast = Toast;//vue的原型添加Toast,在任何地方使用this.$toast 都可以使用Toast 功能
Vue.component(Picker.name,Picker); 
Vue.component(Field.name, Field);
new Vue({
  el: '#app',
  components: { App }
})
//vue页面引用:
<mt-picker :slots="slots" @change="onValuesChange"></mt-picker>

项目页面使用:
首先看下实现效果图:
总共用了三个picker组件,在拨动省组件的时候,市组件会根据省数据联动,区数据会根据市数据联动。(由于我不会贴gif,所以迁就看看吧。)
在这里插入图片描述
这里我把模态框独自封装成了一个子组件mocPicker.vue,又涉及到了父子组件传值的问题,我就不多加赘述。具体代码实现,我会贴出来。
html 部分:

<template>
    <div class="mocPicker">
        <div class="mask" @click.self="_hideLinkage">
            <div class=" linkage">
                <h2>请选择所在地区</h2>
                <div class="linkPageMine clearfix">
                    <div class="province pickerWrapper">
                        <mt-picker :slots="provinces" @change="onProvinceChange" value-key="city_name"></mt-picker>
                    </div>
                    <div class="city pickerWrapper">
                        <mt-picker :slots="citys" @change="onCityChange" value-key="city_name"></mt-picker>
                    </div>
                    <div class="area pickerWrapper">
                        <mt-picker :slots="areas" @change="onAreaChange" value-key="city_name"></mt-picker>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

js部分:

<script>
export default {
    name:'mocPicker',
    props:{
        provinceVal: String,
        cityVal: String,
        districtVal: String,
    },
    computed: {
        result() {
            return {
                province: this.province.city_name,
                city: this.city.city_name,
                district: this.area.city_name,
                provinceId:this.province.city_code,
                cityId: this.city.city_code,
                districtId: this.area.city_code,
            }
        }
    },
    data(){
        return{
            CITY_DATA:[],
            province:{
                city_name: this.provinceVal,
                city_code:'110000'
            },
            maskFlag:false,
            city:{
                city_name:this.cityVal,
                city_code:'110100'
            },
            area:{
                city_name:this.districtVal,
                city_code:'110101'
            },
            flag:0, //最开始省市区那三个picker会初始化调用change事件,但是此时没有省市区数据,因此会报错,
                    //所以以这个标识符来控制当时第一次初始化时调用change事件时直接return
            provinces: [
                {
                    flex: 1,
                    values: [],
                    className: 'slot1',
                    textAlign: 'center'
                }, {
                    divider: true,
                    content: '-',
                    className: 'right'
                }
            ],
            citys: [
                {
                    flex: 1,
                    values: [],
                    className: 'slot1',
                    textAlign: 'center'
                }, {
                    divider: true,
                    content: '-',
                    className: 'slot2'
                }
            ],
            areas: [
                {
                    flex: 1,
                    values: [],
                    className: 'slot1',
                    textAlign: 'center'
                }
            ]
        }
    },
    created(){
        this.CITY_DATA = JSON.parse(decodeURIComponent(localStorage.getItem('regionInfo')));
        this.provinces[0].values = this._getProvince();
        this.citys[0].values = this._getCity('110000');
        this.areas[0].values = this._getArea('110000','110100');
    },
    methods:{
        _hideLinkage(){
            this.$emit('getLinkage',this.result,false); //触发父组件的getLinkage事件接收结果数据
        },
        onProvinceChange(picker, values) {
            if(this.flag===0){
                return
            }
            let provinceIndex=picker.getSlotValue(0)
            this.province=provinceIndex
            let city=this._getCity(this.province.city_code)
            this.citys[0].values=city
            this.city=city[0]
        },
        onCityChange(picker, values) {
            if(this.flag===0){
                return
            }
            let cityIndex=picker.getSlotValue(0);
            this.city=cityIndex
            let provinceIndex=this.province
            let area=this._getArea(this.province.city_code, this.city.city_code)
            this.areas[0].values=area
            this.area=area[0]
        },
        onAreaChange(picker, values) {
            if(this.flag===0){
                this.flag=1
                return
            }
            let areaIndex=picker.getSlotValue(0)
            this.area=areaIndex
        },
         //得到省份数据
        _getProvince(){
            let province=[]
            this.CITY_DATA.forEach(function(item,index){
                let obj={}
                obj.city_code=item.city_code
                obj.city_name=item.city_name
                province.push(obj)
            })
            return province
        },
        //根据省份得到城市数据
        _getCity(provinceId){
            let city=[]
            this.CITY_DATA.forEach((item,index)=>{
                if(item.city_code === provinceId){
                    item.cities.forEach((item,index)=>{
                        let obj={}
                        obj.city_code=item.city_code
                        obj.city_name=item.city_name
                        city.push(obj)
                    })
                }
            })
            return city
        },
        //根据城市和省份得到区域数据
        _getArea(provinceId,cityId){
            let area=[]
            this.CITY_DATA.forEach((item,index)=>{
                if(item.city_code === provinceId){
                    item.cities.forEach((item,index)=>{
                        if(item.city_code === cityId){
                            item.regions.forEach((item)=>{
                                let obj={}
                                obj.city_code=item.city_code
                                obj.city_name=item.city_name
                                area.push(obj)
                            })
                        }
                    })
                }
            })
            if(area.length==0){ //如果没有区域数据则第三个picker显示的内容
                    area.push({
                    city_name:'没有',
                    city_code:'000000'
                })
            }
            return area
        }
    }
}

</script>

css部分:

<style lang="stylus" scoped>
>>>.picker-slot
    font-size: 30px;
    overflow:hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
.mask
    position: fixed;
    top:0;
    left:0;
    width: 100%;
    height: 100%;
    background: rgba(0,0,0,0.5);
    z-index:11;
.linkage
    position: fixed;
    bottom: 0;
    width: 100%;
    height: 50%;
    background: #fff;
    left: 0;
    border-radius: 10px 10px 0 0;
    h2 
        font-size: 32px;
        font-weight: bold;
        padding: 40px 20px;
        text-indent: 1em;
    .linkPageMine
        margin: 50px auto;
        margin-top: 0;
        padding: 30px 0;
        .pickerWrapper
            width:33.3%;
            float: left;
</style>

数据格式,以天津为例:

//具体数据格式,
{
   "city_name":"天津市",
    "cities":[
        {
            "city_name":"天津市",
            "regions":[
                {
                    "city_name":"和平区",
                    "city_pinyin":"hepingqu",
                    "sheng_code":"12",
                    "qu_code":"01",
                    "city_code":"120101",
                    "type":2,
                    "shi_code":"01"
                },
                {
                    "city_name":"河东区",
                    "city_pinyin":"hedongqu",
                    "sheng_code":"12",
                    "qu_code":"02",
                    "city_code":"120102",
                    "type":2,
                    "shi_code":"01"
                },
                {
                    "city_name":"河西区",
                    "city_pinyin":"hexiqu",
                    "sheng_code":"12",
                    "qu_code":"03",
                    "city_code":"120103",
                    "type":2,
                    "shi_code":"01"
                },
                {
                    "city_name":"南开区",
                    "city_pinyin":"nankaiqu",
                    "sheng_code":"12",
                    "qu_code":"04",
                    "city_code":"120104",
                    "type":2,
                    "shi_code":"01"
                },
                {
                    "city_name":"河北区",
                    "city_pinyin":"hebeiqu",
                    "sheng_code":"12",
                    "qu_code":"05",
                    "city_code":"120105",
                    "type":2,
                    "shi_code":"01"
                },
                {
                    "city_name":"红桥区",
                    "city_pinyin":"hongqiaoqu",
                    "sheng_code":"12",
                    "qu_code":"06",
                    "city_code":"120106",
                    "type":2,
                    "shi_code":"01"
                },
                {
                    "city_name":"东丽区",
                    "city_pinyin":"dongliqu",
                    "sheng_code":"12",
                    "qu_code":"10",
                    "city_code":"120110",
                    "type":2,
                    "shi_code":"01"
                },
                {
                    "city_name":"西青区",
                    "city_pinyin":"xiqingqu",
                    "sheng_code":"12",
                    "qu_code":"11",
                    "city_code":"120111",
                    "type":2,
                    "shi_code":"01"
                },
                {
                    "city_name":"津南区",
                    "city_pinyin":"jinnanqu",
                    "sheng_code":"12",
                    "qu_code":"12",
                    "city_code":"120112",
                    "type":2,
                    "shi_code":"01"
                },
                {
                    "city_name":"北辰区",
                    "city_pinyin":"beichenqu",
                    "sheng_code":"12",
                    "qu_code":"13",
                    "city_code":"120113",
                    "type":2,
                    "shi_code":"01"
                },
                {
                    "city_name":"武清区",
                    "city_pinyin":"wuqingqu",
                    "sheng_code":"12",
                    "qu_code":"14",
                    "city_code":"120114",
                    "type":2,
                    "shi_code":"01"
                },
                {
                    "city_name":"宝坻区",
                    "city_pinyin":"baochiqu",
                    "sheng_code":"12",
                    "qu_code":"15",
                    "city_code":"120115",
                    "type":2,
                    "shi_code":"01"
                },
                {
                    "city_name":"滨海新区",
                    "city_pinyin":"binhaixinqu",
                    "sheng_code":"12",
                    "qu_code":"16",
                    "city_code":"120116",
                    "type":2,
                    "shi_code":"01"
                },
                {
                    "city_name":"宁河区",
                    "city_pinyin":"ninghequ",
                    "sheng_code":"12",
                    "qu_code":"17",
                    "city_code":"120117",
                    "type":2,
                    "shi_code":"01"
                },
                {
                    "city_name":"静海区",
                    "city_pinyin":"jinghaiqu",
                    "sheng_code":"12",
                    "qu_code":"18",
                    "city_code":"120118",
                    "type":2,
                    "shi_code":"01"
                },
                {
                    "city_name":"蓟州区",
                    "city_pinyin":"jizhouqu",
                    "sheng_code":"12",
                    "qu_code":"19",
                    "city_code":"120119",
                    "type":2,
                    "shi_code":"01"
                }
            ],
            "city_pinyin":"tianjinshi",
            "sheng_code":"12",
            "qu_code":"00",
            "city_code":"120100",
            "type":1,
            "shi_code":"01"
        }
    ],
    "city_pinyin":"tianjinshi",
    "sheng_code":"12",
    "qu_code":"00",
    "city_code":"120000",
    "type":0,
    "shi_code":"00"
},

父组件引用mocPicker.vue,由于省市区数据太多,我们项目设定市不定期更新,每次请求服务端会返回一个时间戳,前端记录下来并下次请求时将时间戳回传给服务端以此来判断用不用刷新存在localstorage里的省市区数据,来优化用户体验。

// js
import Linkage from './components/mocPicker'
export default {
    components:{
        Linkage,
    },
     data() {
        return {
            province: '',
            city: '',
            district: '',
            mocPickerShow:false,//模态框初始化默认关闭
        }
    },
    methods: {
        // picker组件显示隐藏
        navSeach() {
            this.mocPickerShow = true;
            this.setRegionInfo();
        },
        // 是否更新省市区数据
        setRegionInfo(){
            var lastDistrictVersion = localStorage.getItem('lastDistrictVersion');
            this.$http.get(urlList.getConfiguration+'?lastDistrictVersion='+ lastDistrictVersion).then(res=>{
                if(res.data.code== '200'){
                    var res= res.data.data;
                    this.isNeedUpdate = res.isNeedUpdate;
                    if(this.isNeedUpdate == '1'){
                        this.getRegionInfo();
                    }else{
                        return
                    }
                }
            })
        },
        // 请求省市区三级联动json 
        getRegionInfo(){
            this.$http.get(urlList.regionInfo).then(res=>{
                var res = res.data.data;
                this.lastDistrictVersion = res.districtVersion+'';
                localStorage.setItem('lastDistrictVersion',encodeURIComponent(JSON.stringify(res.districtVersion)))
                localStorage.setItem('regionInfo',encodeURIComponent(JSON.stringify(res.areaInfo)))
            })
        },
        // picker关闭后回传数据
        getLinkage(val,state){
            this.mocPickerShow = state;
            this.province = val.province,
            this.city = val.city,
            this.cityCode = val.districtId;
            this.district = val.district,
            this.addval = this.province +  this.city + this.district ;
        },
    }
}
//html
<Linkage v-show="mocPickerShow" 
  @getLinkage="getLinkage"
   :provinceVal="province"
   :cityVal="city"
   :districtVal="district"
></Linkage>

记:mint-ui 框架定义好的样式,不能随意更改 。如果想要自定义某些样式,style标签不能设置 scoped,否则样式不会生效。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值