• uniapp自定义简单省市区联动组件


    又双叒一个uniapp组件

    最近有一个选择地址的需求,就写了一个省市区联动选择器。

    选择日期使用的picker,就照着它简单的整了一个,使用网络请求城市数据,还用到了vuex组件数据共享。

    本来自己整了一个底部弹窗,又在插件市场看到了更好的底部弹窗 :LuPopupWrapper--弹窗容器, 所以就用了这个。

    依然发布到了插件市场:http://ext.dcloud.net.cn/plugin?id=708

    看一下效果吧

    具体实现

    css就不贴出来了,下载可以看到。

    第一、底部弹出框

    <view class="popup-layout-wrap" :class="popuplayoutClass" >
            <view class="popup-layout-content" :class="popupContentClass" :style="[{height:height}]">
                <slot>
                </slot>
            </view>
            <view v-if="maskShow" class="popup-layout-mask" @tap="close(maskClick)"></view>
    </view>

     这里的底部弹出框用了插件市场的,简单的看一下布局。

    slot插槽用于填充弹出框的内容。

    最主要的就是弹出和关闭。属性就一个height,控制弹出的高度,其他的暂时不需要。

    第二、上下滑动选择城市信息

    分析一波:头部两个按钮,取消和确定。头部下面是选择的城市信息展示。再往下就是最重要的选择操作区。

         选择操作区分成三列,三列分别显示省市区,并且可滑动。当点击选择后,变为红色。

    html代码

            <view class="link-address-wrap">
                    <view class="link-adress-content">
                        <view class="head-wrap">
                            <text class="cancel" @click="btn_cancel">取消</text>
                            <text class="confirm" @click="btn_confirm">确认</text>
                        </view>
                        <view class="head-selected">
                            <text class="selected-txt">已选择:{{selected_address}}</text>
                        </view>
                        <view class="operation-wrap">
                            <view class="operation-container">
                                <view class="operation-content">
                                    <scroll-view
                                        scroll-y="true"
                                        class="province"
                                        show-scrollbar="false">
                                        <view 
                                            :class="{'province-txt':index!==province_current,'province-txt-click':index===province_current}"  
                                            @click="province_txt_click(items.id)" 
                                            v-model="items.id" 
                                            v-for="(items , index) of linkAddress_province"
                                            >
                                                {{items.name}}
                                                <view class="pic" v-show="index===province_current">
                                                    <image src="../../static/xuan-linkAddress/yes.png"></image>
                                                </view>
                                        </view>
                                    </scroll-view>
                                </view>
                                <view class="operation-content">
                                    <scroll-view
                                        scroll-y="true"
                                        class="province"
                                        show-scrollbar="false">
                                        <view 
                                            :class="{'province-txt':index!==city_current,'province-txt-click':index===city_current}"  
                                            @click="city_txt_click(items.id)" 
                                            v-model="items.id" 
                                            v-for="(items , index) of linkAddress_city"
                                            >
                                                {{items.name}}
                                                <view class="pic" v-show="index===city_current">
                                                    <image src="../../static/xuan-linkAddress/yes.png"></image>
                                                </view>
                                        </view>
                                    </scroll-view>
                                </view>
                                <view class="operation-content">
                                    <scroll-view
                                        scroll-y="true"
                                        class="province"
                                        show-scrollbar="false">
                                        <view 
                                            :class="{'province-txt':index!==district_current,'province-txt-click':index===district_current}"  
                                            @click="district_txt_click(items.id)" 
                                            v-model="items.id" 
                                            v-for="(items , index) of linkAddress_district"
                                            >
                                                {{items.name}}
                                                <view class="pic" v-show="index===district_current">
                                                    <image src="../../static/xuan-linkAddress/yes.png"></image>
                                                </view>
                                        </view>
                                    </scroll-view>
                                </view>
                            </view>
                        </view>
                    </view>
                </view>    

     其他的都不用说了,重要的是循环这里。

    分为 未点击样式和点击样式。通过点击元素的index和id匹配来切换状态。

    需要定义的变量

            data(){
                return{
                    /*省市区选择计数*/
                    province_current:null,
                    city_current:null,
                    district_current:null,
                    
                    /*省市区循环数据*/
                    linkAddress_province: [],
                    linkAddress_city: [],
                    linkAddress_district: [],
                    
                    /*请求提交的*/
                    submission:{
                        province:'',//
                        city:'',//
                        county:'',//
                        town:''//
                    },
                    /*用户选择的地址*/
                    user_address:{
                        province:'',//
                        city:'',//
                        district:''//
                    },
                    selected_address:''
                };
            },        

    弹窗显示的时候,去请求省的数据。点击省后请求对应省份的市。

    js代码 只展示点击省的操作,其他的差不多

                //省点击选择
                province_txt_click(target){
                    //区数据值为空
                    this.linkAddress_district= [];
                    //市、区的选择计数置为null
                    this.city_current=null;
                    this.district_current=null;
                    
                    let province;
                    //得到点击的数据,改变样式
                    for (let i = 0; i < this.linkAddress_province.length; i++) {
                        if (this.linkAddress_province[i].id === target) {
                            this.province_current = i;
                            province=this.linkAddress_province[i].name;
                            break;
                        }
                    }
                    //用户选择
                    this.user_address={
                        province:province,
                        city:'',
                        district:''
                    }
                    //请求提交的数据先置为空
                    this.submission={
                        province:'',
                        city:'',
                        county:'',
                        town:''
                    };
                    //再赋值
                    this.submission.province=target;
                    this.selected_address=this.user_address.province;
                    //请求市数据
                    linkAddress_p.get_linkAddress(this,"city",this.submission,(revert)=>{
                        
                    });
                },                

     第三、网络请求

    看官方文档的网络请求后封装一下

    //网络请求
    export default class Request{
        /*
        *paramete 拼接参数
        * data 参数值
        * method 请求方式
        */
        http(paramete,data,method){
            //根地址
            let BASE_API="http://admin.farmereasy.com";
            return new Promise((resolve,reject)=>{
                uni.request({
                    url:`${BASE_API}${paramete}`,
                    data:data,
                    method:method,
                    success:(res)=>{
                        resolve(res);
                    },
                    fail:(res)=>{
                        resolve(0);
                    }
                })
            });
        }
    }
    import Request from "@/static/xuan-linkAddress/request.js"
    //创建Request对象
    let request=new Request();
    
    export default{
        //data 参数值
        get_linkAddress_api:function(data){
            console.log(data);
            return request.http('/api/address/area',data,'GET');
        }
    }

    通过传入不同标签赋给不同的变量。

    import api from '@/components/xuan-linkAddress/api.js';
    
    export default {
        /*
        *_this:全局this
        * data:数据(参数)
        * callback:回掉页面
        */
        get_linkAddress: function(_this,tag,data,callback) {
            //请求
            api.get_linkAddress_api(data).then((res) => {
                let revert=res.data.data;
                console.log(revert)
                if(res.data.code==1){
                    if(tag==="province"){    
                        console.log("province")
                        _this.linkAddress_province=revert;
                        callback(true);//回掉
                    }
                    if(tag==="city"){
                        console.log("city")
                        _this.linkAddress_city=revert;
                        callback(true);//回掉
                    }
                    if(tag==="district"){
                        console.log("district")
                        _this.linkAddress_district=revert;
                        callback(true);//回掉
                    }
                }
            });
        }
    }

    组件就完成了,在具体的页面使用

    <!-- html-->
       <!-- 用于弹出底部框-->
        <button class="popup-btn" @tap="popup_bottom()">请选择</button>
        <!-- 选择组件 -->
        <linkAddress
                ref="linkAddress"
                :height="height"
                @confirmCallback="confirmCallback()"
            >
        </linkAddress>
    
    
      <!-- js-->
      import linkAddress from '../../components/xuan-linkAddress/xuan-linkAddress.vue'
      components:{
            linkAddress
      },
      methods: {
            <!-- 点击弹出-->
            popup_bottom: function() {
                this.height = '550rpx';
                //显示
                this.show_popup();          
            },
            <!-- 显示弹窗-->
            show_popup: function() {
                this.$refs.linkAddress.show();
            },
            <!-- 回掉-->
            confirmCallback: function() {
                     //从vuex中取到用户选择的数据
                //let ads=this.$store.state.user_address;
                //this.address=ads.province+ads.city+ads.district;
            }   
      }

    最后:很简单的一个组件,刚刚开始,希望大家多多包涵,共同学习。

    GitHub地址:https://github.com/steffenx/uniapp_linkaddress

  • 相关阅读:
    VS调试Libevent流程
    Lua require搜索路径指定方法
    关于“无法定位程序输入点gzdirect于动态链接库zlib1.dll”的问题
    poj 1737 Connected Graph
    迭代器挺好用的
    The Balance of the World Aizu
    Country Road Aizu
    牛客小白月赛4 C 病菌感染
    牛客小白月赛4 A 三角形
    老子的全排列呢
  • 原文地址:https://www.cnblogs.com/Steffen-xuan/p/11394829.html
Copyright © 2020-2023  润新知