vue3+vant3封装省市区组件

发布时间 2023-05-19 19:57:33作者: 此夏_唯美

因为后台返回的数据格式和vant不一致,所以自己遍历循环得到自己想到的格式。

省市区的接口并不是一个以children格式,一次性全部获取,而是选择市的时候需要得到省的id,一层一层请求接口才能得到省市区。

 

父组件:

 1 <selectArea
 2         @addressOnFinish="onChangeArea"
 3         :addressObject="addressObject"
 4       />
 5 
 6 import selectArea from "./../components/selectArea";
 7 export default {
 8   components: {
 9     selectArea,
10   },
11     const addressObject = ref({});  //定义子组件对象
12     // 切换区域
13     const onChangeArea = (val) => {
14       console.log(val)//得到省市区,和name
15     };16 
17 return {
18       onChangeArea,
19       addressObject,
20     };

子组件代码:

  1 <template>
  2     <van-nav-bar
  3       :title="addressObject.address"
  4       class="headerTop"
  5       @click-left="onClickBack"
  6     >
  7       <template #right>
  8         <img
  9           src="../../static/assets/change.png"
 10           alt=""
 11           width="20"
 12           @click="addressShow = true"
 13         />
 14       </template>
 15     </van-nav-bar>
 16   
 17     <van-popup v-model:show="addressShow" round position="bottom">
 18       <van-cascader
 19         v-model="addressObject.region"
 20         title="请选择地区"
 21         :options="addressList"
 22         @change="onChange"
 23         @close="addressShow = false"
 24         @finish="addressOnFinish"
 25       />
 26     </van-popup>
 27   </template>
 28   
 29   <script setup>
 30   import { ref, toRefs, defineProps, defineEmits } from "vue";
 31   import { queryArea } from "./../../api/commonApi";
 32   import { closeToast, showLoadingToast } from "vant";
 33   import { useRouter } from "vue-router";
 34   const props = defineProps({
 35     addressObject: Object,
 36   });
 37   const { addressObject } = toRefs(props);
 38   
 39   const addressFieldValue = ref(""); //湖南省/长沙市/芙蓉区
 40   var addressList = ref("");
 41   const addressShow = ref(false);
 42   const addressValue = ref(""); //288
 43   const province = ref("");
 44   const city = ref("");
 45   const region = ref("");
 46   const type = ref("1");
 47   const parentId = ref("");
 48   console.log("addressObject", addressObject.value);
 49   const emit = defineEmits(["addressOnFinish"]);
 50   const router = useRouter();
 51   setTimeout(() => {
 52     // 判断是否有省id 没有是初始化  有是已新增数据并赋值
 53     if (addressObject.value.region) {
 54       var obj = {
 55         type: 2,
 56         parentId: addressObject.value.province,
 57       };
 58       // 根据省id查询市并赋值到children
 59       queryArea(obj)
 60         .then((res) => {
 61           if (res.data.code === 200) {
 62             //  console.log("省循环父id",addressList)
 63             var res = res.data.data;
 64             var options = [];
 65             var obj = {};
 66             // 循环出vant想要的格式
 67             console.log("addressList.value", addressList.value);
 68             console.log("市res", res);
 69             for (let i = 0; i < res.length; i++) {
 70               obj = {
 71                 text: res[i].name,
 72                 value: res[i].id,
 73                 id: res[i].id,
 74                 type: res[i].type,
 75                 children: [], //省里面带children才能出现市区 市区里面带children可出现市区内区划 也就是省市区三级 所以是要把数据拼成这个格式即可
 76               };
 77               options.push(obj);
 78             }
 79             for (let j = 0; j < addressList.value.length; j++) {
 80               if (addressList.value[j].id == addressObject.value.province) {
 81                 addressList.value[j].children = options;
 82                 for (let i = 0; i < options.length; i++) {
 83                   if (options[i].id == addressObject.value.city) {
 84                     // 根据市id查询区并赋值到children
 85                     var params = {
 86                       type: 3,
 87                       parentId: addressObject.value.city,
 88                     };
 89                     queryArea(params)
 90                       .then((res) => {
 91                         if (res.data.code === 200) {
 92                           // console.log("区循环父id",addressList)
 93                           var res = res.data.data;
 94                           var list = [];
 95                           var item = {};
 96                           // 循环出vant想要的格式
 97                           for (let i = 0; i < res.length; i++) {
 98                             item = {
 99                               text: res[i].name,
100                               value: res[i].id,
101                               id: res[i].id,
102                               type: res[i].type,
103                             };
104                             list.push(item);
105                             // console.log("市加children为区并且赋值list",list)
106                             for (
107                               let n = 0;
108                               n < addressList.value[j].children.length;
109                               n++
110                             ) {
111                               if (
112                                 addressList.value[j].children[n].id ==
113                                 addressObject.value.city
114                               ) {
115                                 addressList.value[j].children[n].children = list;
116                                 // 根据市id查询区并赋值到children
117                               }
118                             }
119                           }
120                           // console.log("省加children并且赋值",addressList)
121                         }
122                       })
123                       .catch((error) => {
124                         showToast(error);
125                       });
126                     return;
127                   }
128                 }
129               }
130             }
131             //  console.log("省加children并且赋值",addressList)
132           }
133         })
134         .catch((error) => {});
135     }
136   }, 1000);
137   
138   const onClickBack = () => router.push("/home");
139   const queryAreaData = async () => {
140     var obj = {
141       type: type.value,
142       parentId: parentId.value,
143     };
144     queryArea(obj)
145       .then((res) => {
146         if (res.data.code === 200) {
147           var res = res.data.data;
148           var options = [];
149           var obj = {};
150           for (var i = 0; i < res.length; i++) {
151             obj = {
152               text: res[i].name,
153               value: res[i].id,
154               id: res[i].id,
155               type: res[i].type,
156               children: [], //省里面带children才能出现市区 市区里面带children可出现市区内区划 也就是省市区三级 所以是要把数据拼成这个格式即可
157             };
158             options.push(obj);
159           }
160           addressList.value = options;
161         }
162       })
163       .catch((error) => {});
164   };
165   const onChange = ({ selectedOptions, value, tabIndex }) => {
166     if (tabIndex != 2) {
167       showLoadingToast("加载中...");
168       setTimeout(() => {
169         var obj = {
170           type: tabIndex + 2,
171           parentId: value,
172         };
173         queryArea(obj)
174           .then((res) => {
175             if (res.data.code === 200) {
176               closeToast();
177               var res = res.data.data;
178               var options = [];
179               var obj = {};
180               for (var i = 0; i < res.length; i++) {
181                 // 判断是第几层 不需要 children
182                 if (res[i].type <= 2) {
183                   obj = {
184                     text: res[i].name,
185                     id: res[i].id,
186                     parentId: res[i].parentId,
187                     value: res[i].id,
188                     type: res[i].type,
189                     children: [], //省里面带children才能出现市区 市区里面带children可出现市区内区划 也就是省市区三级 所以是要把数据拼成这个格式即可
190                   };
191                 } else {
192                   obj = {
193                     text: res[i].name,
194                     id: res[i].id,
195                     parentId: res[i].parentId,
196                     value: res[i].id,
197                     type: res[i].type,
198                   };
199                 }
200                 options.push(obj);
201               }
202   
203               selectedOptions[tabIndex].children = options;
204               selectedOptions[tabIndex].children = res.data.data
205                 .map((option) => option.name)
206                 .join("/");
207             }
208           })
209           .catch((error) => {});
210       }, 1000);
211     }
212   };
213   // 全部选项选择完毕后,会触发 finish 事件
214   const addressOnFinish = ({ selectedOptions }) => {
215     addressShow.value = false;
216     addressObject.value.address = selectedOptions
217       .map((option) => option.text)
218       .join("/");
219     for (let i = 0; i < selectedOptions.length; i++) {
220       region.value = selectedOptions[2].id;
221     }
222     // emit("addressOnFinish", region.value);
223     var params = {
224       province: selectedOptions[0].id,
225       city: selectedOptions[1].id,
226       region: region.value,
227       address: addressObject.value.address,
228     };
229     emit("addressOnFinish", params);
230   };
231   
232   queryAreaData();
233   </script>
234