km-tree-select.vue 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. <template>
  2. <div>
  3. <a-tree-select
  4. v-if="editable"
  5. :value="idValue"
  6. :get-popup-container="() => this.$parent.$el"
  7. :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
  8. placeholder="请选择"
  9. :tree-data="computedTreeData"
  10. allow-clear
  11. :tree-default-expand-all="defaultExpandAll"
  12. :replace-fields="replaceFields"
  13. @change="onChange"
  14. >
  15. </a-tree-select>
  16. <span v-else>{{ getDisplayValue(value) }}</span>
  17. </div>
  18. </template>
  19. <script>
  20. import axios from '@/common/services/axios-instance'
  21. import findAncestorComponent from '@/common/services/find-ancestor-component'
  22. import components from './_import-components/km-tree-select-import'
  23. const processArrayInStr = {
  24. getDisplayValue(arr) {
  25. return arr.map((v) => v.name).join(', ')
  26. },
  27. parseBackendValue: (v) => JSON.parse(v),
  28. toBackendValue: (v) => JSON.stringify(v),
  29. }
  30. export default {
  31. name: 'KmTreeSelect',
  32. components,
  33. model: {
  34. prop: 'value',
  35. event: 'change',
  36. },
  37. props: {
  38. value: {
  39. type: [Array, String],
  40. default: undefined,
  41. },
  42. editable: {
  43. type: Boolean,
  44. default: true,
  45. },
  46. treeDataUrl: {
  47. required: true,
  48. type: String,
  49. default: '',
  50. },
  51. // 默认展开所有节点
  52. defaultExpandAll: {
  53. type: Boolean,
  54. default: false,
  55. },
  56. },
  57. data() {
  58. return {
  59. replaceFields: {
  60. title: 'text',
  61. value: 'id',
  62. key: 'id',
  63. },
  64. treeData: [],
  65. }
  66. },
  67. computed: {
  68. idValue() {
  69. if (this.value) {
  70. if (Array.isArray(this.value)) {
  71. return this.value[0].id
  72. } else {
  73. return JSON.parse(this.value)[0].id
  74. }
  75. } else {
  76. return undefined
  77. }
  78. },
  79. // 为了远程数据还未加载时显示text新增的
  80. computedTreeData() {
  81. if (this.treeData.length === 0) {
  82. if (this.value) {
  83. if (Array.isArray(this.value)) {
  84. return this.value.map((item) => {
  85. return { id: item.id, text: item.name }
  86. })
  87. } else {
  88. return JSON.parse(this.value).map((item) => {
  89. return { id: item.id, text: item.name }
  90. })
  91. }
  92. } else {
  93. return []
  94. }
  95. } else {
  96. return this.treeData
  97. }
  98. },
  99. },
  100. created() {
  101. // 只读模式不调接口
  102. if (this.editable) {
  103. this.loadData()
  104. }
  105. // 自动处理 parseBackendValue 等
  106. const item =
  107. findAncestorComponent(this, 'SdFormItemInner') ||
  108. findAncestorComponent(this, 'SdFormItemTdInput')
  109. if (!item || Array.isArray(item.name)) return
  110. this.SdFormContext.fieldOptions[item.name] = {
  111. ...this.SdFormContext.fieldOptions[item.name],
  112. ...processArrayInStr,
  113. dataType: 'array',
  114. }
  115. this.SdFormContext.fieldOptions = { ...this.SdFormContext.fieldOptions }
  116. this.SdFormContext.parseBackendValue(item.name)
  117. },
  118. inject: {
  119. SdFormContext: { default: () => ({}) },
  120. },
  121. methods: {
  122. loadData() {
  123. const req = {
  124. url: this.treeDataUrl,
  125. method: 'get',
  126. }
  127. return axios(req).then((res) => {
  128. if (res.data) {
  129. this.treeData = res.data
  130. }
  131. })
  132. },
  133. onChange(value, label, extra) {
  134. const treeValue = [{ id: value, name: label[0] }]
  135. if (value === undefined) {
  136. this.$emit('change')
  137. } else {
  138. this.$emit('change', treeValue)
  139. }
  140. },
  141. getDisplayValue(arr) {
  142. if (Array.isArray(arr)) {
  143. return arr[0].name
  144. }
  145. },
  146. },
  147. }
  148. </script>
  149. <style module lang="scss">
  150. @use '@/common/design' as *;
  151. </style>