index.vue 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. <template>
  2. <el-select :model-value="transValue"
  3. @update:modelValue="emitSelect"
  4. :clearable="clearable"
  5. :placeholder="placeholder"
  6. filterable
  7. remote
  8. :remote-method="getData"
  9. :allow-create="allowCreate"
  10. :disabled="disabled"
  11. :multiple="multiple"
  12. :style="{width}"
  13. @change="handleChange">
  14. <el-option v-for="(option, index) in options"
  15. :key="index"
  16. :label="option[optionProps.label] ?? option"
  17. :value="option[optionProps.value] ?? option">
  18. </el-option>
  19. </el-select>
  20. </template>
  21. <script>
  22. import { ElSelect, ElOption } from 'element-plus'
  23. import { computed } from 'vue'
  24. import { useFormInput, useOptions } from '@cip/components/hooks/form-input'
  25. import { formInputProps } from '../../form-input-props'
  26. export default {
  27. components: { ElSelect, ElOption },
  28. props: formInputProps,
  29. emits: ['update:modelValue'],
  30. setup (props, context) {
  31. const { width, ...formInput } = useFormInput(props, context)
  32. const { options } = useOptions(props, false, formInput.emitInput)
  33. const remoteMethod = computed(() => {
  34. return props.config?.remoteMethod ?? (() => {})
  35. })
  36. const queryKey = computed(() => {
  37. return props.config?.queryKey ?? ''
  38. })
  39. const allowCreate = computed(() => {
  40. return props.config?.allowCreate ?? false
  41. })
  42. const multiple = computed(() => {
  43. return props.config?.multiple ?? false
  44. })
  45. const splitKey = computed(() => {
  46. return props.config?.splitKey ?? ','
  47. })
  48. const otherKey = computed(() => {
  49. return props.config?.otherKey ?? ''
  50. })
  51. const optionProps = computed(() => {
  52. return Object.assign({
  53. label: 'label',
  54. value: 'value'
  55. }, props.config?.optionProps)
  56. })
  57. const transValue = computed({
  58. get () {
  59. let value = props.modelValue
  60. if (props.config.toType === 'int') {
  61. value = ['', undefined, null].includes(value) ? value : parseInt(value)
  62. } else if (props.config.toType === 'string') {
  63. value = String(value)
  64. }
  65. if (multiple.value && splitKey.value) {
  66. return value ? value.split(splitKey.value) : []
  67. } else {
  68. return value ?? ''
  69. }
  70. }
  71. })
  72. const params = {}
  73. const getData = (query = '') => {
  74. params[queryKey.value] = query
  75. remoteMethod.value(params).then(res => {
  76. options.value = res.data ?? []
  77. })
  78. }
  79. if (props.otherValue) {
  80. // eslint-disable-next-line
  81. params[queryKey.value] = props.otherValue
  82. getData(params)
  83. } else {
  84. getData()
  85. }
  86. const handleChange = async (val) => {
  87. if (otherKey.value) {
  88. let label = ''
  89. if (multiple.value) {
  90. label = []
  91. console.error('basic-select 组件暂不支持多选label配置')
  92. } else {
  93. if (typeof options.value[0] === 'string') {
  94. label = val
  95. } else {
  96. const item = options.value.filter(v => v[optionProps.value.value] === val)[0]
  97. label = item ? item[optionProps.value.label] : null
  98. }
  99. }
  100. context.emit('update:otherValue', label)
  101. }
  102. }
  103. const emitSelect = (val) => {
  104. context.emit('update:modelValue', val)
  105. }
  106. return {
  107. ...formInput,
  108. options,
  109. getData,
  110. allowCreate,
  111. multiple,
  112. transValue,
  113. width,
  114. emitSelect,
  115. handleChange,
  116. optionProps
  117. }
  118. }
  119. }
  120. </script>
  121. <style lang="less" scoped>
  122. .el-select{
  123. width: 100%;
  124. }
  125. </style>