pick-regions.vue 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. <template>
  2. <view class="pick-regions">
  3. <picker mode="multiSelector" :value="multiIndex" :range="multiArray" @change="handleValueChange" @columnchange="handleColumnChange"><slot></slot></picker>
  4. </view>
  5. </template>
  6. <script>
  7. export default {
  8. props: {
  9. defaultRegions: {
  10. type: Array
  11. }
  12. },
  13. data() {
  14. return {
  15. pickerValueArray: [],
  16. cityArr: [],
  17. districtArr: [],
  18. multiIndex: [0, 0, 0],
  19. isInitMultiArray: false,
  20. // 是否加载完默认地区
  21. isLoadDefaultAreas: false
  22. };
  23. },
  24. watch: {
  25. defaultRegions: {
  26. handler(arr, oldArr = []) {
  27. // 避免传的是字面量的时候重复触发
  28. if (arr.length !== 3 || arr.join('') === oldArr.join('')) return;
  29. this.handleDefaultRegions();
  30. },
  31. immediate: true
  32. }
  33. },
  34. computed: {
  35. multiArray() {
  36. if (!this.isLoadDefaultAreas) return;
  37. var arr = this.pickedArr.map(arr => arr.map(item => item.label));
  38. return arr;
  39. },
  40. pickedArr() {
  41. // 进行初始化
  42. if (this.isInitMultiArray) {
  43. return [this.pickerValueArray[0], this.pickerValueArray[1], this.pickerValueArray[2]];
  44. }
  45. return [this.pickerValueArray[0], this.cityArr, this.districtArr];
  46. }
  47. },
  48. created() {
  49. this.getDefaultAreas(0, { level: 0 });
  50. },
  51. methods: {
  52. async handleColumnChange(e) {
  53. this.isInitMultiArray = false;
  54. let col = e.detail.column;
  55. let row = e.detail.value;
  56. this.multiIndex[col] = row;
  57. switch (col) {
  58. case 0:
  59. //选择省,加载市、区县
  60. this.cityArr = await this.getAreasAsync(this.pickerValueArray[0][this.multiIndex[col]].value);
  61. this.districtArr = await this.getAreasAsync(this.cityArr[0].value);
  62. break;
  63. case 1:
  64. //选择市,加载区县
  65. this.districtArr = await this.getAreasAsync(this.cityArr[this.multiIndex[col]].value);
  66. break;
  67. case 2:
  68. break;
  69. }
  70. },
  71. handleValueChange(e) {
  72. // 结构赋值
  73. let [index0, index1, index2] = e.detail.value;
  74. let [arr0, arr1, arr2] = this.pickedArr;
  75. let address = [arr0[index0], arr1[index1], arr2[index2]];
  76. this.$emit('getRegions', address);
  77. },
  78. handleDefaultRegions() {
  79. var time = setInterval(() => {
  80. if (!this.isLoadDefaultAreas) return;
  81. this.isInitMultiArray = false;
  82. for (let i = 0; i < this.defaultRegions.length; i++) {
  83. for (let j = 0; j < this.pickerValueArray[i].length; j++) {
  84. // 匹配省
  85. if (this.defaultRegions[i] == this.pickerValueArray[i][j].value && this.pickerValueArray[i][j].level == 1) {
  86. // 设置选中省
  87. this.$set(this.multiIndex, i, j);
  88. // 查询市
  89. this.getAreas(this.pickerValueArray[i][j].value, data => {
  90. this.cityArr = data;
  91. for (let k = 0; k < this.cityArr.length; k++) {
  92. if (this.defaultRegions[1] == this.cityArr[k].value) {
  93. // 设置选中市
  94. this.$set(this.multiIndex, 1, k);
  95. // 查询区县
  96. this.getAreas(this.cityArr[k].value, data => {
  97. this.districtArr = data;
  98. // 设置选中区县
  99. for (let u = 0; u < this.districtArr.length; u++) {
  100. if (this.defaultRegions[2] == this.districtArr[u].value) {
  101. this.$set(this.multiIndex, 2, u);
  102. this.handleValueChange({
  103. detail: {
  104. value: [j, k, u]
  105. }
  106. });
  107. break;
  108. }
  109. }
  110. });
  111. break;
  112. }
  113. }
  114. });
  115. }
  116. }
  117. }
  118. if (this.isLoadDefaultAreas) clearInterval(time);
  119. }, 100);
  120. },
  121. getDefaultAreas(pid, obj) {
  122. this.$api.sendRequest({
  123. url: '/shopapi/address/lists',
  124. data: { pid: pid },
  125. success: res => {
  126. if (res.code == 0) {
  127. var data = [];
  128. var selected = undefined;
  129. res.data.forEach((item, index) => {
  130. if (obj != undefined) {
  131. if (obj.level == 0 && obj.province_id != undefined) {
  132. selected = obj.province_id;
  133. } else if (obj.level == 1 && obj.city_id != undefined) {
  134. selected = obj.city_id;
  135. } else if (obj.level == 2 && obj.district_id != undefined) {
  136. selected = obj.district_id;
  137. }
  138. }
  139. if (selected == undefined && index == 0) {
  140. selected = item.id;
  141. }
  142. data.push({
  143. value: item.id,
  144. label: item.name,
  145. level: item.level
  146. });
  147. });
  148. this.pickerValueArray[obj.level] = data;
  149. if (obj.level + 1 < 3) {
  150. obj.level++;
  151. this.getDefaultAreas(selected, obj);
  152. } else {
  153. this.isInitMultiArray = true;
  154. this.isLoadDefaultAreas = true;
  155. }
  156. }
  157. }
  158. });
  159. },
  160. // 同步获取地区
  161. async getAreasAsync(pid) {
  162. let res = await this.$api.sendRequest({
  163. url: '/shopapi/address/lists',
  164. data: { pid: pid },
  165. async: false
  166. });
  167. if (res.code == 0) {
  168. var data = [];
  169. res.data.forEach((item, index) => {
  170. data.push({
  171. value: item.id,
  172. label: item.name,
  173. level: item.level
  174. });
  175. });
  176. return data;
  177. }
  178. },
  179. // 异步获取地区
  180. getAreas(pid, callback) {
  181. this.$api.sendRequest({
  182. url: '/shopapi/address/lists',
  183. data: { pid: pid },
  184. success: res => {
  185. if (res.code == 0) {
  186. var data = [];
  187. res.data.forEach((item, index) => {
  188. data.push({
  189. value: item.id,
  190. label: item.name,
  191. level: item.level
  192. });
  193. });
  194. if (callback) callback(data);
  195. }
  196. }
  197. });
  198. }
  199. }
  200. };
  201. </script>