SelectDistrict.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. // 从刚刚安装的库中加载数据
  2. const addressData = require('china-area-data/v5/data');
  3. // 引入 lodash,lodash 是一个实用工具库,提供了很多常用的方法
  4. import _ from 'lodash';
  5. // 注册一个名为 select-district 的 Vue 组件
  6. Vue.component('select-district', {
  7. // 定义组件的属性
  8. props: {
  9. // 用来初始化省市区的值,在编辑时会用到
  10. initValue: {
  11. type: Array, // 格式是数组
  12. default: () => ([]), // 默认是个空数组
  13. }
  14. },
  15. // 定义了这个组件内的数据
  16. data() {
  17. return {
  18. provinces: addressData['86'], // 省列表
  19. cities: {}, // 城市列表
  20. districts: {}, // 地区列表
  21. provinceId: '', // 当前选中的省
  22. cityId: '', // 当前选中的市
  23. districtId: '', // 当前选中的区
  24. };
  25. },
  26. // 定义观察器,对应属性变更时会触发对应的观察器函数
  27. watch: {
  28. // 当选择的省发生改变时触发
  29. provinceId(newVal) {
  30. if (!newVal) {
  31. this.cities = {};
  32. this.cityId = '';
  33. return;
  34. }
  35. // 将城市列表设为当前省下的城市
  36. this.cities = addressData[newVal];
  37. // 如果当前选中的城市不在当前省下,则将选中城市清空
  38. if (!this.cities[this.cityId]) {
  39. this.cityId = '';
  40. }
  41. },
  42. // 当选择的市发生改变时触发
  43. cityId(newVal) {
  44. if (!newVal) {
  45. this.districts = {};
  46. this.districtId = '';
  47. return;
  48. }
  49. // 将地区列表设为当前城市下的地区
  50. this.districts = addressData[newVal];
  51. // 如果当前选中的地区不在当前城市下,则将选中地区清空
  52. if (!this.districts[this.districtId]) {
  53. this.districtId = '';
  54. }
  55. },
  56. // 当选择的区发生改变时触发
  57. districtId() {
  58. // 触发一个名为 change 的 Vue 事件,事件的值就是当前选中的省市区名称,格式为数组
  59. this.$emit('change', [this.provinces[this.provinceId], this.cities[this.cityId], this.districts[this.districtId]]);
  60. },
  61. },
  62. // 组件初始化时会调用这个方法
  63. created() {
  64. this.setFromValue(this.initValue);
  65. },
  66. methods: {
  67. //
  68. setFromValue(value) {
  69. // 过滤掉空值
  70. value = _.filter(value);
  71. // 如果数组长度为0,则将省清空(由于我们定义了观察器,会联动触发将城市和地区清空)
  72. if (value.length === 0) {
  73. this.provinceId = '';
  74. return;
  75. }
  76. // 从当前省列表中找到与数组第一个元素同名的项的索引
  77. const provinceId = _.findKey(this.provinces, o => o === value[0]);
  78. // 没找到,清空省的值
  79. if (!provinceId) {
  80. this.provinceId = '';
  81. return;
  82. }
  83. // 找到了,将当前省设置成对应的ID
  84. this.provinceId = provinceId;
  85. // 由于观察器的作用,这个时候城市列表已经变成了对应省的城市列表
  86. // 从当前城市列表找到与数组第二个元素同名的项的索引
  87. const cityId = _.findKey(addressData[provinceId], o => o === value[1]);
  88. // 没找到,清空城市的值
  89. if (!cityId) {
  90. this.cityId = '';
  91. return;
  92. }
  93. // 找到了,将当前城市设置成对应的ID
  94. this.cityId = cityId;
  95. // 由于观察器的作用,这个时候地区列表已经变成了对应城市的地区列表
  96. // 从当前地区列表找到与数组第三个元素同名的项的索引
  97. const districtId = _.findKey(addressData[cityId], o => o === value[2]);
  98. // 没找到,清空地区的值
  99. if (!districtId) {
  100. this.districtId = '';
  101. return;
  102. }
  103. // 找到了,将当前地区设置成对应的ID
  104. this.districtId = districtId;
  105. }
  106. }
  107. });