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

相關文章
相關標籤/搜索