biaofun-region.vue 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. <!--
  2. * 省市区选择器
  3. * @作者:陈万照
  4. * @公司:山东标梵互动信息技术有限公司
  5. * @官网:http://biaofun.com/
  6. * @微信:C207668802
  7. * @QQ:207668802
  8. * @邮箱:cwz@biaofun.com || 207668802@qq.com
  9. * @版本:v1.0.8
  10. -->
  11. <template>
  12. <view class="region">
  13. <picker mode="multiSelector" :range="range" range-key="name" @change="change" @columnchange="columnchange" :value="value" :disabled="disabled">
  14. <view class="content" :class="{ placeholder: !regionStr }">
  15. <text class="ellipsis-1">{{ regionStr ? regionStr : placeholder }}</text>
  16. </view>
  17. </picker>
  18. </view>
  19. </template>
  20. <script>
  21. const regionData = require('@/static/region.json');
  22. export default {
  23. /**
  24. * 数据
  25. */
  26. props: {
  27. // 是否禁用
  28. disabled: {
  29. type: Boolean,
  30. default: false
  31. },
  32. // placeholder
  33. placeholder: {
  34. type: String,
  35. default: '请选择省/市/区'
  36. },
  37. // 默认值
  38. defaultValue: {
  39. type: Array,
  40. default() {
  41. return null;
  42. }
  43. }
  44. },
  45. /**
  46. * 数据
  47. */
  48. data() {
  49. return {
  50. range: [[], [], []], // 省/市/区
  51. value: [0, 0, 0], // value 的值表示选择了 range 中的第几个(下标从 0 开始),默认为 [0, 0, 0],即 range 为 ['第一个省', '第一个省的第一个市', '第一个省的第一个市的第一个区']
  52. regionStr: '' // 选中的省市区字符串
  53. };
  54. },
  55. /**
  56. * 监听数据
  57. */
  58. watch: {
  59. // 默认值
  60. defaultValue() {
  61. // 设置/更新省市区数据
  62. this.defaultValue ? this.setDefaultValue() : this.setRange();
  63. }
  64. },
  65. /**
  66. * 组件初次加载完成
  67. */
  68. mounted() {
  69. // 设置/更新省市区数据
  70. this.defaultValue ? this.setDefaultValue() : this.setRange();
  71. },
  72. /**
  73. * 函数
  74. */
  75. methods: {
  76. /**
  77. * 设置/更新省市区数据
  78. */
  79. setRange() {
  80. // 省市区数据
  81. let range = [[], [], []];
  82. // 省
  83. regionData.forEach(el => {
  84. range[0].push({
  85. id: el.id,
  86. level: el.level,
  87. name: el.name,
  88. pid: el.pid
  89. });
  90. });
  91. // 市
  92. regionData[this.value[0]].children.forEach(el => {
  93. range[1].push({
  94. id: el.id,
  95. level: el.level,
  96. name: el.name,
  97. pid: el.pid
  98. });
  99. });
  100. // 区
  101. regionData[this.value[0]].children[this.value[1]].children.forEach(el => {
  102. range[2].push({
  103. id: el.id,
  104. level: el.level,
  105. name: el.name,
  106. pid: el.pid
  107. });
  108. });
  109. // 更新省市区数据
  110. this.range = range;
  111. },
  112. /**
  113. * 设置默认值
  114. */
  115. setDefaultValue() {
  116. // 查找省
  117. let provinceIndex = regionData.findIndex(el => {
  118. return el.name == this.defaultValue[0];
  119. });
  120. if(provinceIndex < 0) provinceIndex = 0;
  121. // 查找市
  122. let cityIndex = regionData[provinceIndex].children.findIndex(el => {
  123. return el.name == this.defaultValue[1];
  124. });
  125. if(cityIndex < 0) cityIndex = 0;
  126. // 查找区
  127. let areaIndex = regionData[provinceIndex].children[cityIndex].children.findIndex(el => {
  128. return el.name == this.defaultValue[2];
  129. });
  130. if(areaIndex < 0) areaIndex = 0;
  131. // 更新 value 的值
  132. this.value = [provinceIndex, cityIndex, areaIndex];
  133. // 设置/更新省市区数据
  134. this.setRange();
  135. // 更新选中的省市区字符串
  136. this.regionStr =
  137. regionData[provinceIndex].name + '·' + regionData[provinceIndex].children[cityIndex].name + '·' + regionData[provinceIndex].children[cityIndex].children[areaIndex].name;
  138. },
  139. /**
  140. * 某一列的值改变时触发
  141. * @param {Number} event.detail.column 表示改变了第几列(下标从0开始)
  142. * @param {Number} event.detail.value 表示变更值的下标
  143. */
  144. columnchange(event) {
  145. // 改变的是省
  146. if (event.detail.column == 0) {
  147. this.value = [event.detail.value, 0, 0];
  148. }
  149. // 改变的是市
  150. if (event.detail.column == 1) {
  151. this.value.splice(1, 1, event.detail.value);
  152. this.value.splice(2, 1, 0);
  153. }
  154. // 改变的是区
  155. if (event.detail.column == 2) {
  156. this.value.splice(2, 1, event.detail.value);
  157. }
  158. // 设置/更新省市区数据
  159. this.setRange();
  160. },
  161. /**
  162. * 确认选择
  163. */
  164. change(event) {
  165. // 更新选中的省市区字符串
  166. this.regionStr = this.range[0][this.value[0]].name + '·' + this.range[1][this.value[1]].name + '·' + this.range[2][this.value[2]].name;
  167. // 传递事件
  168. this.$emit('change', [this.range[0][this.value[0]], this.range[1][this.value[1]], this.range[2][this.value[2]]]);
  169. }
  170. }
  171. };
  172. </script>
  173. <style lang="scss" scoped>
  174. .ellipsis-1 {
  175. display: -webkit-box;
  176. -webkit-box-orient: vertical;
  177. -webkit-line-clamp: 1;
  178. overflow: hidden;
  179. }
  180. .content {
  181. text-align: right;
  182. }
  183. .placeholder {
  184. color: #949596;
  185. }
  186. </style>