@ithinkdt/naive
Version:
iThinkDT Naive UI
65 lines (54 loc) • 1.87 kB
JSX
import { defineComponent, ref, onUnmounted, watch } from 'vue'
import { NDynamicInput } from 'ithinkdt-ui'
import { debounce } from '@ithinkdt/common'
import { toReactive } from '@vueuse/core'
import { Sortable } from 'sortablejs/modular/sortable.core.esm.js'
export const DtArrayInput = defineComponent({
name: 'DtArrayInput',
props: {
value: { type: Array, default: () => [] },
},
emits: {
'update-value': () => true,
'update:value': () => true,
},
setup(props, { emit, slots, expose }) {
const emitValue = (v) => {
emit('update:value', v)
emit('update-value', v)
}
const input = ref({})
expose(toReactive(input))
let sortable
const updateSortable = debounce((el) => {
if (!el) return
sortable?.destroy()
sortable = Sortable.create(el, {
animation: 150,
onEnd({ newIndex, oldIndex }) {
if (newIndex === undefined || oldIndex === undefined) return
const array = [...props.value]
const [o] = array.splice(oldIndex, 1)
array.splice(newIndex, 0, o)
emitValue(array)
},
})
}, 300)
onUnmounted(() => {
sortable?.destroy()
})
watch([() => props.value, () => input.value.$el], ([_, el]) => updateSortable(el))
return () => {
return (
<NDynamicInput
ref={input}
value={props.value}
onUpdate:value={(v) => emit('update:value', v)}
onUpdateValue={(v) => emit('update-value', v)}
>
{slots}
</NDynamicInput>
)
}
},
})