返回 slidev
v-drag.ts
根目录 / packages / client / modules / v-drag.ts
1 import type { App } from 'vue'
2 import type { DragElementState } from '../composables/useDragElements'
3 import { watch } from 'vue'
4 import { useDragElement } from '../composables/useDragElements'
5
6 export function createVDragDirective() {
7 return {
8 install(app: App) {
9 app.directive<HTMLElement & { draggingState: DragElementState }>('drag', {
10 // @ts-expect-error extra prop
11 name: 'v-drag',
12
13 created(el, binding, vnode) {
14 const state = useDragElement(binding, binding.value, vnode.props?.markdownSource)
15 if (vnode.props) {
16 vnode.props = { ...vnode.props }
17 delete vnode.props.markdownSource
18 }
19 state.container.value = el
20 el.draggingState = state
21 el.dataset.dragId = state.dragId
22 state.watchStopHandles.push(
23 watch(state.containerStyle, (style) => {
24 for (const [k, v] of Object.entries(style)) {
25 if (v)
26 el.style[k as any] = v as any
27 }
28 }, { immediate: true }),
29 )
30 el.addEventListener('dblclick', state.startDragging)
31 },
32 mounted(el) {
33 el.draggingState.mounted()
34 },
35 unmounted(el) {
36 const state = el.draggingState
37 state.unmounted()
38 el.removeEventListener('dblclick', state.startDragging)
39 state.watchStopHandles.forEach(fn => fn())
40 },
41 })
42 },
43 }
44 }
45
45 lines TYPESCRIPT