DraggableNest.vue 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. <script lang="tsx">
  2. import { defineComponent, PropType, ExtractPropTypes, computed, unref, onMounted, ref } from 'vue'
  3. import { LeTableColumnProps } from '@/components/Table/index.d'
  4. import { useI18n } from 'vue-i18n'
  5. import Draggable from 'vuedraggable'
  6. import Icon from '@/components/Icon'
  7. /*export type DraggableProps = {
  8. level: number
  9. value: any[]
  10. form: any[]
  11. options: any
  12. setFixed: () => void
  13. remove: (item, index, inputs) => void
  14. move: () => void
  15. }
  16. // 接受父组件参数,配置默认值
  17. const props = withDefaults(defineProps<DraggableProps>(), {
  18. level: 0,
  19. value: undefined,
  20. /!** default: {
  21. t_label: String, // 多语言关键key
  22. label?: String, // 若不存在t_label 可使用 label
  23. prop: String, // 用于 作为唯一值鉴定用
  24. // checked: Boolean, // 当前配置 是否选中(主要用于 后期有children 的情况)
  25. fixed?: Boolean||String, // fixed 的不允许删除 disabled
  26. children?: Option[] // 同上配置
  27. }[] *!/
  28. // form: undefined,
  29. options: {},
  30. setFixed: () => {},
  31. remove: (item, index, inputs) => {
  32. console.error(item, index, inputs, 'remove')
  33. // if (!item.fixed) {
  34. // inputs.splice(index, 1)
  35. // this.$emit('input', inputs)
  36. // }
  37. },
  38. move: (...args) => console.error(args, 'move')
  39. })
  40. export type DraggableEmits = {
  41. (e: 'input', value: any): void
  42. (e: 'start', value: any): void
  43. (e: 'end', value: any): void
  44. }
  45. const emits = defineEmits<DraggableEmits>()*/
  46. const draggableProps = {
  47. level: {
  48. type: Number,
  49. default: 0
  50. },
  51. modelValue: {
  52. required: false,
  53. /** default: {
  54. t_label: String, // 多语言关键key
  55. label?: String, // 若不存在t_label 可使用 label
  56. prop: String, // 用于 作为唯一值鉴定用
  57. // checked: Boolean, // 当前配置 是否选中(主要用于 后期有children 的情况)
  58. fixed?: Boolean||String, // fixed 的不允许删除 disabled
  59. children?: Option[] // 同上配置
  60. }[] */
  61. type: Array as PropType<LeTableColumnProps[]>,
  62. default: null
  63. },
  64. list: {
  65. required: false,
  66. type: Array as PropType<LeTableColumnProps[]>,
  67. default: null
  68. },
  69. options: {
  70. type: Object,
  71. default: () => ({})
  72. },
  73. // todo: 扩展预设 设置定位(置顶/底)
  74. // setFixed: {
  75. // type: Function,
  76. // default: (...args) => {}
  77. // },
  78. remove: {
  79. type: Function,
  80. default: (item, index, inputs) => {
  81. console.error(item, index, inputs, 'removeHandler')
  82. // if (!item.fixed) {
  83. // inputs.splice(index, 1)
  84. // this.$emit('input', inputs)
  85. // }
  86. }
  87. },
  88. move: {
  89. type: Function,
  90. default: (...args) => {
  91. console.error(args, 'move')
  92. }
  93. }
  94. }
  95. export type DraggableProps = ExtractPropTypes<typeof draggableProps>
  96. const draggableEmits = {
  97. ['update:modelValue']: ((value: LeTableColumnProps[]) => value),
  98. // start: (value: any) => void 0,
  99. // end: (value: any) => void 0
  100. }
  101. export type DraggableEmits = typeof draggableEmits
  102. const DraggableNest = defineComponent({
  103. name: 'LeDraggableNest',
  104. props: draggableProps,
  105. emits: draggableEmits,
  106. setup(props, { emit, slots }) {
  107. const { t } = useI18n()
  108. const realValue = computed(() => {
  109. return props.modelValue ? props.modelValue : props.list
  110. })
  111. const dragOptions = computed(() => {
  112. return {
  113. animation: 280,
  114. group: 'description',
  115. disabled: false,
  116. ghostClass: 'ghost',
  117. chosenClass: 'chosen',
  118. itemKey: 'prop',
  119. ...props.options
  120. }
  121. })
  122. const emitter = values => {
  123. // console.error(values, 'emit(\'update:modelValue\', values)')
  124. emit('update:modelValue', values)
  125. }
  126. const slots_item = {
  127. item: ({ element: v, index }) => {
  128. const _label = v.t_label ? t(v.t_label) : v.label
  129. return <div class="le-draggable-nest-item" key={v.prop}>
  130. <div
  131. class={['itemWrap', `${(v.fixed) ? 'disabled' : ''}`]}
  132. // onClick={() => this.removeHandler(v, index, this.realValue)}
  133. >
  134. <el-checkbox size="default" class={props.level !== 0 ? 'checkbox-hide' : ''} disabled={!!v.fixed || props.level !== 0} modelValue={true} onChange={props.remove.bind(null, v, index, realValue.value)} />
  135. <span class="label_txt" title={_label}>{ _label }</span>
  136. <Icon class="dragEl" iconClass="le-drag"/>
  137. </div>
  138. {
  139. (v.children || []).length ? <LeDraggableNest
  140. group={v.prop}
  141. move={props.move}
  142. // remove={props.remove}
  143. level={props.level + 1}
  144. list={v.children}
  145. /> : ''
  146. }
  147. </div>
  148. }
  149. }
  150. return () => {
  151. return (
  152. <Draggable
  153. class="le-draggable-nest"
  154. {...dragOptions.value}
  155. list={props.list}
  156. modelValue={props.modelValue}
  157. onUpdate:modelValue={emitter}
  158. move={props.move}
  159. v-slots={slots_item}
  160. />
  161. )
  162. }
  163. }
  164. })
  165. export default DraggableNest
  166. </script>