index.tsx 3.6 KB
Newer Older
1
import { defineComponent, Ref, ref, onMounted, provide } from 'vue'
fxy060608's avatar
fxy060608 已提交
2
import { movableAreaProps } from '../../components/movableArea'
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
import { flatVNode } from '../../helpers/flatVNode'
import { TouchtrackEvent } from '../movable-view/useTouchtrack'
import { getComponentSize } from '../helpers'
export interface MovableViewContext {
  setParent: Function
}
export type AddMovableViewContext = (context: MovableViewContext) => void
export type RemoveMovableViewContext = (context: MovableViewContext) => void

interface TouchMovableViewContext {
  touchstart: (e: TouchtrackEvent) => void
  touchmove: (e: TouchtrackEvent) => void
  touchend: (e: TouchtrackEvent) => void
}
export type SetTouchMovableViewContext = (
  context: TouchMovableViewContext | null
) => void

type RootRef = Ref<HTMLElement | null>
export interface parentSize {
  width: Ref<number>
  height: Ref<number>
  top: Ref<number>
  left: Ref<number>
}

export default defineComponent({
  name: 'MovableArea',
fxy060608's avatar
fxy060608 已提交
31
  props: movableAreaProps,
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
  styles: [
    {
      'uni-movable-area': {
        width: '10px',
        height: '10px',
      },
    },
  ],
  setup(props, { slots }) {
    const width = ref(0)
    const height = ref(0)
    const top = ref(0)
    const left = ref(0)
    const _isMounted = ref(false)
    const rootRef: RootRef = ref(null)
    const originMovableViewContexts: MovableViewContext[] = []
    let touchMovableView: null | TouchMovableViewContext = null

    const setTouchMovableViewContext: SetTouchMovableViewContext = (
      movableview
    ) => {
      touchMovableView = movableview
    }

    const _getWH = () => {
      return getComponentSize(rootRef.value!).then(
        ({ width: _width, height: _height, top: _top, left: _left }) => {
          width.value = _width
          height.value = _height
          top.value = _top
          left.value = _left
        }
      )
    }

    const _resize = () => {
      _getWH().then(() => {
        originMovableViewContexts.forEach(function (item) {
          item.setParent()
        })
      })
    }

    onMounted(() => {
      // 由于weex在mounted后渲染是异步的不能确保元素渲染完成,需要延迟执行
      setTimeout(() => {
        _isMounted.value = true
        _resize()
      }, 200)
    })

    const listeners = {
      onPanstart(e: TouchtrackEvent) {
        touchMovableView && touchMovableView.touchstart(e)
      },
      onPanmove(e: TouchtrackEvent) {
        e.stopPropagation()
        touchMovableView && touchMovableView.touchmove(e)
      },
      onPanend(e: TouchtrackEvent) {
        touchMovableView && touchMovableView.touchend(e)
      },
    }
    const addMovableViewContext: AddMovableViewContext = (
      movableViewContext
    ) => {
      originMovableViewContexts.push(movableViewContext)
    }
    const removeMovableViewContext: RemoveMovableViewContext = (
      movableViewContext
    ) => {
      const index = originMovableViewContexts.indexOf(movableViewContext)
      if (index >= 0) {
        originMovableViewContexts.splice(index, 1)
      }
    }
    provide('_isMounted', _isMounted)
    provide('parentSize', {
      width: width,
      height: height,
      top: top,
      left: left,
    })
    provide('addMovableViewContext', addMovableViewContext)
    provide('removeMovableViewContext', removeMovableViewContext)
    provide('setTouchMovableViewContext', setTouchMovableViewContext)

    return () => {
      const defaultSlots = slots.default && slots.default()
      const movableViewItems = flatVNode(defaultSlots)
      return (
D
DCloud_LXH 已提交
123
        <view class="uni-movable-area" {...listeners}>
124
          {movableViewItems}
D
DCloud_LXH 已提交
125
        </view>
126 127 128 129
      )
    }
  },
})