index.vue 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. <!-- 嵌套列表 -->
  2. <template>
  3. <div :style="{ width: item.width ? item.width + 'px' : '100%' }">
  4. <v-text-field
  5. v-bind="props"
  6. id="menu-activator"
  7. v-model="model_selectLabel"
  8. variant="outlined" hide-spin-buttons
  9. :density="item.dense || 'compact'"
  10. :type="item.type"
  11. :rules="item.rules"
  12. :disabled="item.disabled"
  13. :style="{width: item.width}"
  14. :color="item.color || 'primary'"
  15. :label="item.label"
  16. :placeholder="item.placeholder || item.label"
  17. :autofocus="item.autofocus"
  18. :required="item.required"
  19. :class="item.class"
  20. :suffix="item.suffix"
  21. :append-icon="item.appendIcon"
  22. :append-inner-icon="item.appendInnerIcon"
  23. :clearable="item.clearable"
  24. :readonly="item.readonly"
  25. :counter="item.counter"
  26. :prepend-inner-icon="item.prependInnerIcon"
  27. :hide-details="item.hideDetails || false"
  28. @update:modelValue="modelValueUpDate"
  29. >
  30. </v-text-field>
  31. <v-menu activator="#menu-activator" :close-on-content-click="closeOnContentClick">
  32. <listGroup
  33. :list="item.items"
  34. :option="option"
  35. :selectValue="value"
  36. class="px-1"
  37. style="max-height: 258px; border-radius: 5px;"
  38. @labelUpdate="labelTxt => labelUpdateDeal(labelTxt)"
  39. @clickUpdate="val => clickUpdate(val)"
  40. ></listGroup>
  41. </v-menu>
  42. </div>
  43. </template>
  44. <script setup>
  45. import listGroup from './components/listGroup'
  46. import { ref } from 'vue';
  47. defineOptions({ name:'FormUI-nestedListGroup'})
  48. const propsData = defineProps({item: Object, modelValue: [String, Number]})
  49. const item = propsData.item
  50. const option = {
  51. ...item,
  52. itemValue: item.itemValue || 'value',
  53. itemText: item.itemText || 'label',
  54. multiply: item.multiply || false, // 多选(待开发
  55. selectLevel: item.selectLevel || -1, // 可选层级,-1代表只能选最后一级
  56. relate: item.relate || false,
  57. items: []
  58. }
  59. const emit = defineEmits(['update:modelValue', 'change'])
  60. const modelValueUpDate = () => {
  61. model_selectLabel.value = option.rules ? static_selectLabel : '' // 必填时不可删除,非必填时则直接删除
  62. }
  63. let static_selectLabel = ''; const model_selectLabel = ref('')
  64. const value = ref(propsData.modelValue) // selectValue // modelValue
  65. const clickUpdate = (val) => {
  66. static_selectLabel = model_selectLabel.value = val[option.itemText || 'label']
  67. value.value = val[option.itemValue || 'value']
  68. emit('update:modelValue', value.value)
  69. emit('change', value.value)
  70. }
  71. const closeOnContentClick = ref(false) // multiple
  72. // 回显label
  73. const chosen = ref(null)
  74. const traverse = (nodes) => {
  75. for (const node of nodes) {
  76. if (node[option.itemValue || value] === value.value) {
  77. chosen.value = node
  78. }
  79. if (node.children) {
  80. traverse(node.children)
  81. }
  82. }
  83. }
  84. if (item?.items?.length && value.value) traverse(item.items)
  85. if (chosen.value) clickUpdate(chosen.value)
  86. </script>
  87. <style lang="scss" scoped>
  88. .showOnTop {
  89. bottom: 62px;
  90. }
  91. ::-webkit-scrollbar {
  92. width: 4px;
  93. height: 10px;
  94. // display: none;
  95. }
  96. ::-webkit-scrollbar-thumb, .temporaryAdd ::-webkit-scrollbar-thumb, .details_edit ::-webkit-scrollbar-thumb {
  97. // 滚动条-颜色
  98. background: #c3c3c379;
  99. }
  100. ::-webkit-scrollbar-track, .temporaryAdd ::-webkit-scrollbar-track, .details_edit ::-webkit-scrollbar-track {
  101. // 滚动条-底色
  102. background: #e5e5e58f;
  103. }
  104. </style>