uni-app省市区选择器

2020-08-12  本文已影响0人  MiSiTeWang

现在大多数的省市区选择器都是三级滚动联动的,有时候可能不是我们所想要的,所以就自己做了一个选择器,效果如下:

20191109095738520.png
具体实现代码如下:
需要导入省市区的数据city.area.js以及弹窗组件uni-pop.vue,
city.area.js文件在百度网盘,如需要请自取(链接:https://pan.baidu.com/s/1V7hYksMtOH96UpwAy_nEPw
提取码:adds)

<template>
    <view>
        <view @tap="togglePopup('bottom','popup')" style="padding: 40upx;display: flex;align-items: center;">
            <view v-for="(item, index) in selectList" :key="index">
                {{item.txt}}<span v-show="index == 0 || index == 1">—</span>
            </view>
        </view>
        <uni-popup ref="popup" :type="type" @change="change">
            <view class="select-border">
                <view class="header">
                    <view class="title">
                        选择地区
                    </view>
                    <view class="cancel-icon" @tap="cancel('popup')">
                        X
                    </view>
                </view>
                <view class="select-box">
                    <view class="select-item">
                        <view class="select-list" @tap="tabEvent(index)" :class="indexTab == index ? 'selected' : ''" v-for="(item, index) in selectList"
                         :key="index">
                            {{item.txt}}
                        </view>
                    </view>
                    <view class="select-item-box">
                        <!-- 省 -->
                        <view class="province-box" v-show="proviceShow">
                            <view class="select-list-cont" @tap="provinceEvent(item,index)" v-for="(item,index) in provinceData" :key="item.code">
                                {{item.name}}<span class="check" v-show="index == checkOne">√</span>
                            </view>
                        </view>
                        <!-- 市 -->
                        <view class="city-box" v-show="cityShow">
                            <view class="select-list-cont" @tap="cityEvent(item,index)" v-for="(item,index) in cityData" :key="item.code">
                                {{item.name}}<span class="check" v-show="index==checkTwo">√</span>
                            </view>
                        </view>
                        <!-- 区 -->
                        <view class="area-box" v-show="areaShow">
                            <view class="select-list-cont" @tap="areaEvent(item,index)" v-for="(item,index) in areaData" :key="item.code">
                                {{item.name}}<span class="check" v-show="index==checkThree">√</span>
                            </view>
                        </view>
                    </view>
                </view>
            </view>
        </uni-popup>
    </view>
</template>
 
<script>
    import cityDatas from '../../components/mpvue-citypicker/city-data/city.area.js'
    import uniPopup from '@/components/uni-popup/uni-popup.vue'
    export default {
        components: {
            uniPopup
        },
        data() {
            return {
                provinceData: cityDatas,
                cityData: [],
                areaData: [],
                selectList: [{
                    txt: '请选择'
                }, {
                    txt: '请选择'
                }, {
                    txt: '请选择'
                }],
                tabOne: '请选择',
                indexTab: 0,
                proviceShow: true,
                areaShow: false,
                cityShow: false,
                show: false,
                type: '',
                checkOne: null,
                checkTwo: null,
                checkThree: null,
            }
        },
        onLoad() {
 
        },
        watch: {
 
        },
        methods: {
            togglePopup(type, open) {
                this.type = type
                if (open === 'tip') {
                    this.show = true
                } else {
                    this.$refs[open].open()
                }
            },
            cancel(type) {
                if (type === 'tip') {
                    this.show = false
                    return
                }
                this.$refs[type].close()
            },
            change(e) {
                if (e.show == true) {
                    uni.hideTabBar()
                } else {
                    uni.showTabBar()
                }
            },
            tabEvent(index) {
                this.indexTab = index
                if (this.indexTab == 0) {
                    this.proviceShow = true
                    this.cityShow = false
                    this.areaShow = false
                    // this.checkOne = null
                    this.checkTwo = null
                    this.checkThree = null
                    // this.cityData = []
                    this.areaData = []
                    // this.selectList[0].txt = "请选择"
                    this.selectList[1].txt = "请选择"
                    this.selectList[2].txt = "请选择"
                } else if (this.indexTab == 1) {
                    this.proviceShow = false
                    this.cityShow = true
                    this.areaShow = false
                    // this.checkTwo = null
                    this.checkThree = null
                    // this.areaData = []
                    // this.selectList[1].txt = "请选择"
                    this.selectList[2].txt = "请选择"
                } else if (this.indexTab == 2) {
                    this.proviceShow = false
                    this.cityShow = false
                    this.areaShow = true
                }
            },
            provinceEvent(data, index) {
                this.checkOne = index
                this.selectList[0].txt = data.name
                this.indexTab = 1
                this.proviceShow = false
                this.cityShow = true
                this.areaShow = false
                this.cityData = data.cityList
            },
            cityEvent(data, index) {
                this.checkTwo = index
                this.selectList[1].txt = data.name
                this.indexTab = 2
                this.proviceShow = false
                this.cityShow = false
                this.areaShow = true
                this.areaData = data.areaList
            },
            areaEvent(data, index) {
                this.checkThree = index
                this.selectList[2].txt = data.name
            }
        }
    }
</script>
 
<style>
    .header {
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 35upx;
    }
 
    .title {
        font-size: 34upx;
        font-family: PingFang SC;
        font-weight: bold;
        color: rgba(51, 51, 51, 1);
    }
 
    .cancel-icon {
        font-size: 34upx;
        color: rgba(153, 153, 153, 1);
    }
 
    .check {
        padding-left: 17upx;
        color: #FF7E28;
    }
 
    .select-box {
        height: 1024upx;
    }
 
    .select-item {
        display: flex;
        align-items: center;
        padding-left: 50upx;
        margin-bottom: 20upx;
        border-bottom: 1px solid #F6F6F6;
    }
 
    .select-list {
        width: 120upx;
        height: 40upx;
        text-align: center;
        overflow: hidden;
        /*超出部分隐藏*/
        text-overflow: ellipsis;
        /* 超出部分显示省略号 */
        white-space: nowrap;
        /*规定段落中的文本不进行换行 */
        font-size: 30upx;
        font-family: PingFang SC;
        font-weight: bold;
        color: rgba(51, 51, 51, 1);
        margin-right: 30upx;
        border-bottom: 1px solid #FFFFFF;
    }
 
    .select-list-cont {
        padding-left: 67upx;
        font-size: 30upx;
        font-family: PingFang SC;
        font-weight: 500;
        color: rgba(51, 51, 51, 1);
        line-height: 40px;
    }
 
    .selected {
        border-bottom: 1px solid #F0AD4E;
        color: rgba(255, 133, 0, 1);
    }
</style>

uni-pop.vue代码如下:

<template>
    <view v-if="showPopup" class="uni-popup">
        <view :class="[ani, animation ? 'ani' : '', !custom ? 'uni-custom' : '']" class="uni-popup__mask" @click="close(true)" />
        <view :class="[type, ani, animation ? 'ani' : '', !custom ? 'uni-custom' : '']" class="uni-popup__wrapper" @click="close(true)">
            <view class="uni-popup__wrapper-box" @click.stop="clear">
                <slot />
            </view>
        </view>
    </view>
</template>
 
<script>
    export default {
        name: 'UniPopup',
        props: {
            // 开启动画
            animation: {
                type: Boolean,
                default: true
            },
            // 弹出层类型,可选值,top: 顶部弹出层;bottom:底部弹出层;center:全屏弹出层
            type: {
                type: String,
                default: 'center'
            },
            // 是否开启自定义
            custom: {
                type: Boolean,
                default: false
            },
            // maskClick
            maskClick: {
                type: Boolean,
                default: true
            },
            show: {
                type: Boolean,
                default: true
            }
        },
        data() {
            return {
                ani: '',
                showPopup: false
            }
        },
        watch: {
            show(newValue) {
                if (newValue) {
                    this.open()
                } else {
                    this.close()
                }
            }
        },
        created() {},
        methods: {
            clear() {},
            open() {
                this.$emit('change', {
                    show: true
                })
                this.showPopup = true
                this.$nextTick(() => {
                    setTimeout(() => {
                        this.ani = 'uni-' + this.type
                    }, 30)
                })
            },
            close(type) {
                if (!this.maskClick && type) return
                this.$emit('change', {
                    show: false
                })
                this.ani = ''
                this.$nextTick(() => {
                    setTimeout(() => {
                        this.showPopup = false
                    }, 300)
                })
            }
        }
    }
</script>
<style>
    @charset "UTF-8";
 
    .uni-popup {
        position: fixed;
        top: 0;
        top: 0;
        bottom: 0;
        left: 0;
        right: 0;
        z-index: 998;
        overflow: hidden
    }
 
    .uni-popup__mask {
        position: absolute;
        top: 0;
        bottom: 0;
        left: 0;
        right: 0;
        z-index: 998;
        background: rgba(0,0,0,0.75);
        opacity: 0
    }
 
    .uni-popup__mask.ani {
        transition: all .3s
    }
 
    .uni-popup__mask.uni-bottom,
    .uni-popup__mask.uni-center,
    .uni-popup__mask.uni-top {
        opacity: 1
    }
 
    .uni-popup__wrapper {
        position: absolute;
        z-index: 999;
        box-sizing: border-box
    }
 
    .uni-popup__wrapper.ani {
        transition: all .3s
    }
 
    .uni-popup__wrapper.top {
        top: 0;
        left: 0;
        width: 100%;
        transform: translateY(-100%)
    }
 
    .uni-popup__wrapper.bottom {
        bottom: 0;
        left: 0;
        width: 100%;
        transform: translateY(100%);
    }
 
    .uni-popup__wrapper.center {
        width: 100%;
        height: 100%;
        display: flex;
        justify-content: center;
        align-items: center;
        transform: scale(1.2);
        opacity: 0
    }
 
    .uni-popup__wrapper-box {
        position: relative;
        box-sizing: border-box;
    }
 
    .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
        /* padding: 30upx; */
        background: #fff;
        background: rgba(255, 255, 255, 1);
        border-radius: 12px 12px 0px 0px;
    }
 
    .uni-popup__wrapper.uni-custom.center .uni-popup__wrapper-box {
        position: relative;
        /* max-width: 80%;
        max-height: 80%; */
        overflow-y: scroll
    }
 
    .uni-popup__wrapper.uni-custom.bottom .uni-popup__wrapper-box,
    .uni-popup__wrapper.uni-custom.top .uni-popup__wrapper-box {
        width: 100%;
        /* max-height: 500px; */
        overflow-y: scroll
    }
 
    .uni-popup__wrapper.uni-bottom,
    .uni-popup__wrapper.uni-top {
        transform: translateY(0)
    }
 
    .uni-popup__wrapper.uni-center {
        transform: scale(1);
        opacity: 1
    }
</style>

文章转载于https://blog.csdn.net/lemontealin/article/details/102983836

上一篇下一篇

猜你喜欢

热点阅读