pick-regions.vue 6.1 KB

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