DySelectTree.vue 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. <script setup lang="ts">
  2. import { ref, toRefs, withDefaults, onMounted } from "vue"
  3. import Treeselect from "vue3-treeselect-ts"
  4. import "vue3-treeselect-ts/dist/style.css"
  5. import type { AxiosRequestConfig } from "axios"
  6. import Rs from "@/core/services/RequestService"
  7. interface TreeOption {
  8. id: string
  9. label: string
  10. children?: Array<TreeOption>
  11. }
  12. const props = withDefaults(
  13. defineProps<{
  14. value: string | null | undefined
  15. name?: string
  16. url?: string
  17. configs?: AxiosRequestConfig
  18. multiple?: boolean
  19. clearable?: boolean
  20. searchable?: boolean
  21. expandedKeys?: Array<string>
  22. defaultExpandLevel?: number
  23. placeholder?: string
  24. loadingText?: string
  25. staticOptions?: Array<TreeOption>
  26. dataFormatFunction?: (data: any) => TreeOption
  27. optionMap?: {
  28. id: string
  29. label: string
  30. children: string
  31. }
  32. }>(),
  33. {
  34. multiple: false,
  35. clearable: false,
  36. searchable: false,
  37. staticOptions: () => {
  38. return [] as Array<TreeOption>
  39. },
  40. optionMap: () => {
  41. return {
  42. id: "id",
  43. label: "name",
  44. children: "children",
  45. }
  46. },
  47. placeholder: "请选择...",
  48. loadingText: "加载中,请稍后...",
  49. }
  50. )
  51. const emits = defineEmits<{
  52. (e: "update:value", v: string): void
  53. (e: "select", v: any): void
  54. }>()
  55. const { staticOptions, url, value } = toRefs(props)
  56. const options = ref<Array<TreeOption>>(staticOptions.value ?? [])
  57. function formatData(data: any) {
  58. if (props.dataFormatFunction) {
  59. return props.dataFormatFunction(data)
  60. } else {
  61. const item = {} as TreeOption
  62. if (props.optionMap.id in data) {
  63. item.id = data[props.optionMap.id]
  64. }
  65. if (props.optionMap.label in data) {
  66. item.label = data[props.optionMap.label]
  67. }
  68. if (props.optionMap.children in data) {
  69. const childrenItem = [] as Array<TreeOption>
  70. const children = data[props.optionMap.children]
  71. children.forEach((v: any) => {
  72. childrenItem.push(formatData(v))
  73. })
  74. item.children = childrenItem
  75. }
  76. return item
  77. }
  78. }
  79. function init() {
  80. if (url?.value) {
  81. const configs = Object.assign({}, { url: url.value, method: "get", successAlert: false }, props.configs)
  82. Rs.request(configs).then((res: any) => {
  83. //const data = [] as Array<TreeOption>
  84. res.data.forEach((v: any) => {
  85. const item = formatData(v)
  86. options.value.push(item)
  87. })
  88. if (!value.value) {
  89. const val = options.value[0].id
  90. emits("update:value", val)
  91. }
  92. })
  93. }
  94. }
  95. function onSelect(data: any) {
  96. //console.log("data", data, data.id)
  97. emits("update:value", data.id)
  98. emits("select", data)
  99. }
  100. onMounted(() => {
  101. init()
  102. })
  103. </script>
  104. <template>
  105. <treeselect
  106. v-model="value"
  107. :placeholder="placeholder"
  108. :loadingText="loadingText"
  109. :multiple="multiple"
  110. :options="options"
  111. :clearable="clearable"
  112. :searchable="searchable"
  113. :name="name"
  114. :default-expand-level="defaultExpandLevel"
  115. v-bind="$attrs"
  116. @select="onSelect"
  117. />
  118. </template>