JAreaLinkage.vue 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. <template>
  2. <div v-if="!reloading" class="j-area-linkage">
  3. <area-cascader
  4. v-if="_type === enums.type[0]"
  5. :value="innerValue"
  6. :data="pcaa"
  7. :level="1"
  8. :style="{width}"
  9. v-bind="$attrs"
  10. v-on="_listeners"
  11. @change="handleChange"
  12. />
  13. <area-select
  14. v-else-if="_type === enums.type[1]"
  15. :value="innerValue"
  16. :data="pcaa"
  17. :level="2"
  18. v-bind="$attrs"
  19. v-on="_listeners"
  20. @change="handleChange"
  21. />
  22. <div v-else>
  23. <span style="color:red;"> Bad type value: {{_type}}</span>
  24. </div>
  25. </div>
  26. </template>
  27. <script>
  28. import { pcaa } from 'area-data'
  29. import Area from '@/components/_util/Area'
  30. export default {
  31. name: 'JAreaLinkage',
  32. props: {
  33. value: {
  34. type: String,
  35. required:false
  36. },
  37. // 组件的类型,可选值:
  38. // select 下拉样式
  39. // cascader 级联样式(默认)
  40. type: {
  41. type: String,
  42. default: 'cascader'
  43. },
  44. width: {
  45. type: String,
  46. default: '100%'
  47. }
  48. },
  49. data() {
  50. return {
  51. pcaa,
  52. innerValue: [],
  53. usedListeners: ['change'],
  54. enums: {
  55. type: ['cascader', 'select']
  56. },
  57. reloading: false,
  58. areaData:''
  59. }
  60. },
  61. computed: {
  62. _listeners() {
  63. let listeners = { ...this.$listeners }
  64. // 去掉已使用的事件,防止冲突
  65. this.usedListeners.forEach(key => {
  66. delete listeners[key]
  67. })
  68. return listeners
  69. },
  70. _type() {
  71. if (this.enums.type.includes(this.type)) {
  72. return this.type
  73. } else {
  74. console.error(`JAreaLinkage的type属性只能接收指定的值(${this.enums.type.join('|')})`)
  75. return this.enums.type[0]
  76. }
  77. },
  78. },
  79. watch: {
  80. value: {
  81. immediate: true,
  82. handler() {
  83. this.loadDataByValue(this.value)
  84. }
  85. },
  86. },
  87. created() {
  88. this.initAreaData();
  89. },
  90. methods: {
  91. /** 通过 value 反推 options */
  92. loadDataByValue(value) {
  93. if(!value || value.length==0){
  94. this.innerValue = []
  95. this.reloading = true;
  96. setTimeout(()=>{
  97. this.reloading = false
  98. },100)
  99. }else{
  100. this.initAreaData();
  101. let arr = this.areaData.getRealCode(value);
  102. this.innerValue = arr
  103. }
  104. },
  105. /** 通过地区code获取子级 */
  106. loadDataByCode(value) {
  107. let options = []
  108. let data = pcaa[value]
  109. if (data) {
  110. for (let key in data) {
  111. if (data.hasOwnProperty(key)) {
  112. options.push({ value: key, label: data[key], })
  113. }
  114. }
  115. return options
  116. } else {
  117. return []
  118. }
  119. },
  120. /** 判断是否有子节点 */
  121. hasChildren(options) {
  122. options.forEach(option => {
  123. let data = this.loadDataByCode(option.value)
  124. option.isLeaf = data.length === 0
  125. })
  126. },
  127. handleChange(values) {
  128. let value = values[values.length - 1]
  129. this.$emit('change', value)
  130. },
  131. initAreaData(){
  132. if(!this.areaData){
  133. this.areaData = new Area();
  134. }
  135. },
  136. },
  137. model: { prop: 'value', event: 'change' },
  138. }
  139. </script>
  140. <style lang="less" scoped>
  141. .j-area-linkage {
  142. height:40px;
  143. ::v-deep .area-cascader-wrap .area-select {
  144. width: 100%;
  145. }
  146. ::v-deep .area-select .area-selected-trigger {
  147. line-height: 1.15;
  148. }
  149. }
  150. </style>