DragHandle.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
  2. import { createVNode as _createVNode } from "vue";
  3. import addEventListenerWrap from '../../vc-util/Dom/addEventListener';
  4. import raf from '../../_util/raf';
  5. import { defineComponent, onUnmounted, computed, shallowRef, watchEffect, getCurrentInstance } from 'vue';
  6. import devWarning from '../../vc-util/devWarning';
  7. import { useInjectTableContext } from '../../table/context';
  8. import supportsPassive from '../../_util/supportsPassive';
  9. const events = {
  10. mouse: {
  11. start: 'mousedown',
  12. move: 'mousemove',
  13. stop: 'mouseup'
  14. },
  15. touch: {
  16. start: 'touchstart',
  17. move: 'touchmove',
  18. stop: 'touchend'
  19. }
  20. };
  21. const defaultMinWidth = 50;
  22. export default defineComponent({
  23. compatConfig: {
  24. MODE: 3
  25. },
  26. name: 'DragHandle',
  27. props: {
  28. prefixCls: String,
  29. width: {
  30. type: Number,
  31. required: true
  32. },
  33. minWidth: {
  34. type: Number,
  35. default: defaultMinWidth
  36. },
  37. maxWidth: {
  38. type: Number,
  39. default: Infinity
  40. },
  41. column: {
  42. type: Object,
  43. default: undefined
  44. }
  45. },
  46. setup(props) {
  47. let startX = 0;
  48. let moveEvent = {
  49. remove: () => {}
  50. };
  51. let stopEvent = {
  52. remove: () => {}
  53. };
  54. const removeEvents = () => {
  55. moveEvent.remove();
  56. stopEvent.remove();
  57. };
  58. onUnmounted(() => {
  59. removeEvents();
  60. });
  61. watchEffect(() => {
  62. devWarning(!isNaN(props.width), 'Table', 'width must be a number when use resizable');
  63. });
  64. const {
  65. onResizeColumn
  66. } = useInjectTableContext();
  67. const minWidth = computed(() => {
  68. return typeof props.minWidth === 'number' && !isNaN(props.minWidth) ? props.minWidth : defaultMinWidth;
  69. });
  70. const maxWidth = computed(() => {
  71. return typeof props.maxWidth === 'number' && !isNaN(props.maxWidth) ? props.maxWidth : Infinity;
  72. });
  73. const instance = getCurrentInstance();
  74. let baseWidth = 0;
  75. const dragging = shallowRef(false);
  76. let rafId;
  77. const updateWidth = e => {
  78. let pageX = 0;
  79. if (e.touches) {
  80. if (e.touches.length) {
  81. // touchmove
  82. pageX = e.touches[0].pageX;
  83. } else {
  84. // touchend
  85. pageX = e.changedTouches[0].pageX;
  86. }
  87. } else {
  88. pageX = e.pageX;
  89. }
  90. const tmpDeltaX = startX - pageX;
  91. let w = Math.max(baseWidth - tmpDeltaX, minWidth.value);
  92. w = Math.min(w, maxWidth.value);
  93. raf.cancel(rafId);
  94. rafId = raf(() => {
  95. onResizeColumn(w, props.column.__originColumn__);
  96. });
  97. };
  98. const handleMove = e => {
  99. updateWidth(e);
  100. };
  101. const handleStop = e => {
  102. dragging.value = false;
  103. updateWidth(e);
  104. removeEvents();
  105. };
  106. const handleStart = (e, eventsFor) => {
  107. dragging.value = true;
  108. removeEvents();
  109. baseWidth = instance.vnode.el.parentNode.getBoundingClientRect().width;
  110. if (e instanceof MouseEvent && e.which !== 1) {
  111. return;
  112. }
  113. if (e.stopPropagation) e.stopPropagation();
  114. startX = e.touches ? e.touches[0].pageX : e.pageX;
  115. moveEvent = addEventListenerWrap(document.documentElement, eventsFor.move, handleMove);
  116. stopEvent = addEventListenerWrap(document.documentElement, eventsFor.stop, handleStop);
  117. };
  118. const handleDown = e => {
  119. e.stopPropagation();
  120. e.preventDefault();
  121. handleStart(e, events.mouse);
  122. };
  123. const handleTouchDown = e => {
  124. e.stopPropagation();
  125. e.preventDefault();
  126. handleStart(e, events.touch);
  127. };
  128. const handleClick = e => {
  129. e.stopPropagation();
  130. e.preventDefault();
  131. };
  132. return () => {
  133. const {
  134. prefixCls
  135. } = props;
  136. const touchEvents = {
  137. [supportsPassive ? 'onTouchstartPassive' : 'onTouchstart']: e => handleTouchDown(e)
  138. };
  139. return _createVNode("div", _objectSpread(_objectSpread({
  140. "class": `${prefixCls}-resize-handle ${dragging.value ? 'dragging' : ''}`,
  141. "onMousedown": handleDown
  142. }, touchEvents), {}, {
  143. "onClick": handleClick
  144. }), [_createVNode("div", {
  145. "class": `${prefixCls}-resize-handle-line`
  146. }, null)]);
  147. };
  148. }
  149. });