又雙叒一個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,控制彈出的高度,其餘的暫時不須要。
分析一波:頭部兩個按鈕,取消和肯定。頭部下面是選擇的城市信息展現。再往下就是最重要的選擇操做區。
選擇操做區分紅三列,三列分別顯示省市區,而且可滑動。當點擊選擇後,變爲紅色。
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; } }
最後:很簡單的一個組件,剛剛開始,但願你們多多包涵,共同窗習。