一、通過vue mint-ui 最終實現的效果
二、省市區對應的數據格式
1 const address = [{ 2 "code": "11", 3 "name": "北京市", 4 "children": [{ 5 "code": "1101", 6 "name": "市轄區", 7 "children": [{ 8 "code": "110101", 9 "name": "東城區" 10 }, { 11 "code": "110102", 12 "name": "西城區" 13 }] 14 }] 15 }]
三、通過vue、mint 實現組件
1 <template> 2 <div class="form-item"> 3 <mt-cell title="家庭地址" is-link @click.native="showPopup"> 4 <span>{{currentTags}}</span> 5 </mt-cell> 6 <mt-popup 7 v-model="popupVisible" 8 position="bottom" 9 :modal = "true" 10 :closeOnClickModal = "false" 11 popup-transition="popup-fade" 12 style="width : 100%;"> 13 <mt-picker 14 :slots="addressList" 15 :show-toolbar="true" 16 ref="familyAddress" 17 :itemHeight = 44 18 valueKey="name" 19 @change = "onValuesChange" 20 > 21 <slot> 22 <div class="toolbar"> 23 <span class="cancel-container" @click="cancelChoose">取消</span> 24 <span class="confirm-container" @click="confirmChoose">確認</span> 25 </div> 26 </slot> 27 </mt-picker> 28 </mt-popup> 29 </div> 30 </template>
四、選擇對應的省市區實現的業務邏輯
1 export default { 2 name: "cityPicker", 3 data(){ 4 return { 5 address : null, 6 currentTags : "請選擇", 7 handler: function(e){ 8 e.preventDefault() 9 }, 10 popupVisible:false, 11 province:'',//省 12 city:'',//市 13 county:'',//縣 14 provinceCode:'',//省級代碼 15 cityCode:'', //市級代碼 16 countyCode:'',//縣級代碼 17 regionInit:false,//禁止地區選擇器自動初始化,picker組件會默認進行初始化,導致一進入頁面就會默認選中一個初始3級地址 18 } 19 }, 20 created(){ 21 // 獲取所有省市區 22 axios.get("/api/address").then(res => { 23 if(res){ 24 this.address = res 25 } 26 }) 27 }, 28 methods: { 29 closeTouch () { 30 document.getElementsByTagName('body')[0].addEventListener('touchmove', this.handler, {passive:false})//阻止默認事件 31 }, 32 openTouch () { 33 document.getElementsByTagName('body')[0].removeEventListener('touchmove', this.handler, {passive:false})//打開默認事件 34 }, 35 getProvinceArr() { 36 let provinceArr = []; 37 if(this.address){ 38 this.address.forEach(function (item) { 39 let obj = {}; 40 obj.name = item.name; 41 obj.code = item.code; 42 provinceArr.push(obj); 43 }); 44 } 45 return provinceArr; 46 }, 47 //遍歷json,返回市級對象數組 48 getCityArr(province) { 49 let cityArr = []; 50 if(this.address){ 51 this.address.forEach(function (item) { 52 if (item.name === province) { 53 item.children.forEach(function (args) { 54 let obj = {}; 55 obj.name = args.name; 56 obj.code = args.code; 57 cityArr.push(obj); 58 }); 59 } 60 }); 61 } 62 return cityArr; 63 }, 64 //遍歷json,返回縣級對象數組 65 getCountyArr(province,city){ 66 let countyArr = []; 67 if(this.address){ 68 this.address.forEach(function(item) { 69 if (item.name === province) { 70 item.children.forEach(function (args) { 71 if (args.name === city) { 72 args.children.forEach(function (param) { 73 let obj = {}; 74 obj.name = param.name; 75 obj.code = param.code; 76 countyArr.push(obj); 77 }) 78 } 79 }); 80 } 81 }) 82 } 83 return countyArr; 84 }, 85 showPopup(){ 86 this.popupVisible = true 87 this.closeTouch(); 88 }, 89 cancelChoose(){ 90 this.popupVisible = false; 91 this.openTouch(); 92 }, 93 confirmChoose(){ 94 let vals = this.$refs.familyAddress.getValues() 95 this.getFamilyAddress(vals) 96 this.popupVisible = false; 97 this.openTouch(); 98 }, 99 getFamilyAddress(vals){ 100 this.province = vals[0].name 101 this.city = vals[1].name 102 this.county = vals[2].name 103 this.provinceCode = vals[0].code 104 this.cityCode = vals[1].code 105 this.countyCode = vals[0].code 106 this.currentTags = this.province + this.city + this.county 107 }, 108 onValuesChange(picker, values) { 109 if (this.regionInit){ 110 let provinceArr = this.getProvinceArr(); 111 picker.setSlotValues(0,provinceArr); 112 let cityArr = this.getCityArr(values[0].name); 113 picker.setSlotValues(1,cityArr); 114 let countyArr = this.getCountyArr(values[0].name,values[1].name); 115 picker.setSlotValues(2,countyArr); 116 }else { 117 this.regionInit = true; 118 } 119 } 120 }, 121 computed:{ 122 addressList : function(){ 123 if(this.address){ 124 let provinceArr = this.getProvinceArr(); 125 let cityArr = this.getCityArr("北京市"); 126 let countyArr = this.getCountyArr("北京市","市轄區"); 127 return [ 128 { 129 flex: 1, 130 values: provinceArr, //省份數組 131 className: 'slot1', 132 textAlign: 'center' 133 }, 134 { 135 divider: true, 136 content: '-', 137 className: 'slot2' 138 }, 139 { 140 flex: 1, 141 values: cityArr, 142 className: 'slot3', 143 textAlign: 'center' 144 }, 145 { 146 divider: true, 147 content: '-', 148 className: 'slot4' 149 }, 150 { 151 flex: 1, 152 values: countyArr, 153 className: 'slot5', 154 textAlign: 'center' 155 } 156 ] 157 } 158 return [] 159 } 160 } 161 }
五、部分css樣式
1 <style scoped lang="less"> 2 .toolbar{ 3 width : 100%; 4 display: flex; 5 text-align: center; 6 background: #F7F7F7; 7 border-bottom: 1px solid #EEE; 8 span{ 9 flex : 1; 10 font-size : 16px; 11 color : #26a2ff; 12 line-height: 44px; 13 } 14 } 15 </style>