uniapp自定義簡單省市區聯動組件

又雙叒一個uniapp組件css

最近有一個選擇地址的需求,就寫了一個省市區聯動選擇器。html

選擇日期使用的picker,就照着它簡單的整了一個,使用網絡請求城市數據,還用到了vuex組件數據共享。vue

原本本身整了一個底部彈窗,又在插件市場看到了更好的底部彈窗 :LuPopupWrapper--彈窗容器, 因此就用了這個。git

依然發佈到了插件市場:http://ext.dcloud.net.cn/plugin?id=708github

看一下效果吧vuex

具體實現

css就不貼出來了,下載能夠看到。api

第1、底部彈出框
網絡

<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>

 這裏的底部彈出框用了插件市場的,簡單的看一下佈局。app

slot插槽用於填充彈出框的內容。佈局

最主要的就是彈出和關閉。屬性就一個height,控制彈出的高度,其餘的暫時不須要。

第2、上下滑動選擇城市信息

分析一波:頭部兩個按鈕,取消和肯定。頭部下面是選擇的城市信息展現。再往下就是最重要的選擇操做區。

     選擇操做區分紅三列,三列分別顯示省市區,而且可滑動。當點擊選擇後,變爲紅色。

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)=>{
                    
                });
            },                

 第3、網絡請求

看官方文檔的網絡請求後封裝一下

//網絡請求
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

相關文章
相關標籤/搜索