app-area-picker.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. <template>
  2. <view class="dir-left-nowrap cross-center">
  3. <!-- #ifdef MP-WEIXIN || MP-BAIDU || H5 -->
  4. <picker class="box-grow-1 area-picker-left"
  5. mode="multiSelector"
  6. @change="bindMultiPickerChange"
  7. @columnchange="bindMultiPickerColumnChange"
  8. :value="multiIndex"
  9. range-key="name"
  10. :range="multiArray">
  11. <text v-if="place!==`请选择`" class="address-name-color">{{place}}</text>
  12. <text v-else class="address-place-name-color">{{place}}</text>
  13. </picker>
  14. <!-- #endif -->
  15. <!-- #ifdef MP-ALIPAY || MP-TOUTIAO -->
  16. <view class="area-picker-left" @click="showAreaPicker">
  17. <text v-if="place!==`请选择`" class="address-name-color">{{place}}</text>
  18. <text v-else class="address-place-name-color">{{place}}</text>
  19. </view>
  20. <view class="area-picker" :class="area_picker_show">
  21. <view class="area-picker-bg" bindtap="hideAreaPicker">
  22. <scroll-view></scroll-view>
  23. </view>
  24. <view class="area-picker-body">
  25. <scroll-view>
  26. <view class="area-picker-top">
  27. <text class="area-picker-cancel" @click="hideAreaPicker">取消</text>
  28. <text class="area-picker-confirm" @click="areaPickerConfirm">确认</text>
  29. </view>
  30. <view class="area-picker-row">
  31. <picker-view v-if="multiIndex && multiIndex.length" indicator-style="height: 50px" style="width: 100%; height: 250px;"
  32. :value="multiIndex" @change="areaPickerChange">
  33. <picker-view-column>
  34. <view v-if="multiArray[0]" v-for="(item,index) in multiArray[0]" :key="index"
  35. style="line-height: 50px;height: 50px;text-align: center">{{item.name}}
  36. </view>
  37. </picker-view-column>
  38. <picker-view-column>
  39. <view v-if="multiArray[1]" v-for="(item,index) in multiArray[1]" :key="index"
  40. style="line-height: 50px;height: 50px;text-align: center">{{item.name}}
  41. </view>
  42. </picker-view-column>
  43. <picker-view-column>
  44. <view v-if="multiArray[2]" v-for="(item,index) in multiArray[2]" :key="index"
  45. style="line-height: 50px;height: 50px;text-align: center">{{item.name}}
  46. </view>
  47. </picker-view-column>
  48. </picker-view>
  49. </view>
  50. </scroll-view>
  51. </view>
  52. </view>
  53. <!-- #endif -->
  54. <image class="box-grow-0 arrow-image" src="/static/image/icon/arrow-right.png"></image>
  55. </view>
  56. </template>
  57. <script>
  58. export default {
  59. name: "app-area-picker",
  60. props: {
  61. ids: {
  62. type: Array,
  63. default: function () {
  64. return []
  65. }
  66. }
  67. },
  68. data() {
  69. return {
  70. tempIds : this.ids,
  71. area_picker_show: '',
  72. list: [],
  73. multiIndex: [],
  74. multiArray: [],
  75. place: '',
  76. }
  77. },
  78. created: function () {
  79. this.tempIds = this.tempIds.concat();
  80. },
  81. watch: {
  82. ids: {
  83. handler:function (newData,oldData){
  84. this.tempIds = this.ids;
  85. },
  86. },
  87. tempIds: {
  88. handler:function (newData,oldData){
  89. const self = this;
  90. self.before((data) => {
  91. self.init(data);
  92. })
  93. this.$emit('ids', this.tempIds);
  94. },
  95. deep: true,
  96. immediate: true,
  97. },
  98. },
  99. methods: {
  100. //#ifdef MP-ALIPAY || MP-TOUTIAO
  101. showAreaPicker: function () {
  102. this.area_picker_show = 'active';
  103. },
  104. hideAreaPicker: function () {
  105. this.area_picker_show = '';
  106. },
  107. areaPickerConfirm: function (e) {
  108. this.bindMultiPickerChange({detail: {value: this.multiIndex}});
  109. this.hideAreaPicker();
  110. },
  111. areaPickerChange: function (e) {
  112. const self = this;
  113. if (self.area_picker_show == '') return;
  114. let detail = {
  115. column: '',
  116. value: '',
  117. };
  118. for (let i = 0; i < 3; i++) {
  119. if (e.detail.value[i] !== self.multiIndex[i]) {
  120. detail.column = i;
  121. detail.value = e.detail.value[i];
  122. break;
  123. }
  124. }
  125. self.multiIndex = e.detail.value;
  126. self.bindMultiPickerColumnChange({detail: detail});
  127. },
  128. //#endif
  129. before(cb) {
  130. const self = this;
  131. const district = this.$storage.getStorageSync("_DISTRICT");
  132. if (district) {
  133. cb(district);
  134. } else {
  135. this.$request({
  136. url: self.$api.default.district,
  137. }).then(info => {
  138. if (info.code === 0) {
  139. this.$storage.setStorageSync("_DISTRICT", info.data.list);
  140. cb(info.data.list);
  141. }
  142. })
  143. }
  144. },
  145. init: function (list) {
  146. const null_status = this.tempIds.length === 3 && this.tempIds[0] != 0;
  147. const ids = null_status ? this.tempIds : [2, 3, 4];
  148. const multiIndex = this.getIndex(list, ids);
  149. const multiArray = [
  150. list,
  151. list[multiIndex[0]].list,
  152. list[multiIndex[0]].list[multiIndex[1]].list
  153. ];
  154. let place = multiArray[0][multiIndex[0]].name
  155. + ','
  156. + multiArray[1][multiIndex[1]].name
  157. + ','
  158. + multiArray[2][multiIndex[2]].name;
  159. /////初始化
  160. let eve = [
  161. multiArray[0][multiIndex[0]],
  162. multiArray[1][multiIndex[1]],
  163. multiArray[2][multiIndex[2]],
  164. ];
  165. ////
  166. this.setEvent(eve, null_status);
  167. [this.list, this.multiArray, this.multiIndex, this.place] = [list, multiArray, multiIndex, null_status ? place : '请选择']
  168. },
  169. getIndex: function (list, data) {
  170. let arr = [];
  171. list.map((item, index) => {
  172. if (data[0] == item.id) arr.push(index)
  173. });
  174. list[arr[0]].list.map((item, index) => {
  175. if (data[1] == item.id) arr.push(index)
  176. });
  177. list[arr[0]].list[arr[1]].list.map((item, index) => {
  178. if (data[2] == item.id) arr.push(index);
  179. });
  180. return arr;
  181. },
  182. bindMultiPickerChange: function (e) {
  183. let list = [
  184. this.multiArray[0][e.detail.value[0]],
  185. this.multiArray[1][e.detail.value[1]],
  186. this.multiArray[2][e.detail.value[2]],
  187. ];
  188. let place = list[0].name
  189. + ','
  190. + list[1].name
  191. + ','
  192. + list[2].name;
  193. [this.multiIndex, this.place] = [e.detail.value, place];
  194. this.setEvent(list);
  195. },
  196. setEvent: function (list, status = true) {
  197. let data = {
  198. province: {
  199. id: list[0].id,
  200. name: list[0].name
  201. },
  202. city: {
  203. id: list[1].id,
  204. name: list[1].name
  205. },
  206. district: {
  207. id: list[2].id,
  208. name: list[2].name
  209. },
  210. };
  211. this.$emit('customevent', status ? data : null);
  212. },
  213. bindMultiPickerColumnChange: function (e) {
  214. let data = {
  215. multiArray: this.multiArray,
  216. multiIndex: this.multiIndex
  217. };
  218. data.multiIndex[e.detail.column] = e.detail.value;
  219. switch (e.detail.column) {
  220. case 0:
  221. data.multiIndex.splice(1, 1, 0);
  222. data.multiIndex.splice(2, 1, 0);
  223. data.multiArray.splice(1, 1, this.list[data.multiIndex[0]].list);
  224. data.multiArray.splice(2, 1, this.list[data.multiIndex[0]].list[data.multiIndex[1]].list);
  225. break;
  226. case 1:
  227. data.multiIndex.splice(2, 1, 0);
  228. data.multiArray.splice(2, 1, this.list[data.multiIndex[0]].list[data.multiIndex[1]].list);
  229. break;
  230. }
  231. [this.multiArray, this.multiIndex] = [data.multiArray, data.multiIndex]
  232. },
  233. },
  234. }
  235. </script>
  236. <style scoped lang="scss">
  237. .area-picker-left {
  238. min-width: #{115rpx};
  239. font-size: #{28rpx};
  240. padding-right: #{24rpx};
  241. line-height: 1.5;
  242. margin-left: auto;
  243. .address-name-color {
  244. color: #353535;
  245. }
  246. .address-place-name-color {
  247. color: #999999;
  248. }
  249. }
  250. .arrow-image {
  251. width: #{12rpx};
  252. height: #{24rpx};
  253. }
  254. /* #ifdef MP-ALIPAY || MP-TOUTIAO */
  255. .area-picker {
  256. position: fixed;
  257. z-index: 1600;
  258. left: 0;
  259. top: 0;
  260. width: 100%;
  261. height: 100%;
  262. display: flex;
  263. flex-direction: column;
  264. transform: translateY(100%);
  265. transition: 250ms opacity;
  266. opacity: 0;
  267. background: rgba(0, 0, 0, .3);
  268. }
  269. .area-picker.active {
  270. transform: translateY(0);
  271. opacity: 1;
  272. }
  273. .area-picker .area-picker-bg {
  274. flex-grow: 1;
  275. position: relative;
  276. }
  277. .area-picker .area-picker-bg > scroll-view {
  278. left: 0;
  279. top: 0;
  280. height: 100%;
  281. width: 100%;
  282. position: absolute;
  283. }
  284. .area-picker .area-picker-body {
  285. flex-grow: 0;
  286. height: #{600rpx};
  287. background: #fff;
  288. transform: translateY(100%);
  289. transition: 250ms transform;
  290. position: relative;
  291. }
  292. .area-picker.active .area-picker-body {
  293. transform: translateY(0);
  294. }
  295. .area-picker .area-picker-body > scroll-view {
  296. left: 0;
  297. top: 0;
  298. height: 100%;
  299. width: 100%;
  300. position: absolute;
  301. }
  302. .area-picker .area-picker-cancel,
  303. .area-picker .area-picker-confirm {
  304. display: inline-block;
  305. padding: #{24rpx};
  306. color: #888;
  307. }
  308. .area-picker .area-picker-confirm {
  309. float: right;
  310. color: #00aa00;
  311. }
  312. .area-picker .area-picker-row {
  313. width: 100%;
  314. height: #{500rpx};
  315. }
  316. /* #endif */
  317. </style>