123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- <template>
- <div class="drag-container" v-show="show">
- <slot />
- </div>
- </template>
- <script lang="ts">
- import {
- defineComponent,
- reactive,
- toRefs,
- onMounted,
- watch,
- watchEffect
- } from 'vue';
- export default defineComponent({
- props: {
- show: {
- type: Boolean,
- default: () => false
- },
- domClassName: {
- type: String,
- default: ''
- }
- },
- setup(props: any, ctx: any) {
- const data = reactive({
- show: false,
- domClassName: '',
- startPosition: {
- left: '',
- top: '',
- cssText: ''
- }
- });
- watchEffect(() => {
- data.show = props.show;
- data.domClassName = props.domClassName;
- });
- onMounted(() => {
- const dragDom = document.getElementsByClassName(
- props.domClassName ? props.domClassName : 'drag-container'
- )[0] as HTMLElement;
- if (!dragDom) return;
- let isDrag = false;
- watch(
- () => data.show,
- (newVal, oldVal) => {
- data.show = newVal;
- if (newVal === oldVal) return;
- if (data.show === true) {
- dragDom.style.left = data.startPosition?.left;
- dragDom.style.top = data.startPosition?.top;
- dragDom.style.cssText = data.startPosition?.cssText;
- }
- }
- );
- const mouseDown = (e: MouseEvent) => {
- isDrag = true;
- const X = e.clientX - dragDom.offsetLeft;
- const Y = e.clientY - dragDom.offsetTop;
- const move = (e: MouseEvent) => {
- e.preventDefault();
- if (isDrag) {
- dragDom.style.left = `${e.clientX - X}Px`;
- dragDom.style.top = `${e.clientY - Y}Px`;
- }
- };
- document.addEventListener('mousemove', throttle(move, 20), false);
- document.addEventListener('mouseup', () => {
- isDrag = false;
- document.removeEventListener('mousemove', move);
- });
- };
- dragDom.addEventListener('mousedown', mouseDown);
- });
- function throttle(
- fn: { (e: MouseEvent): void; apply?: any },
- timer: number
- ) {
- let initTime = 0;
- return function (...args: any) {
- const nowTime = +new Date();
- if (nowTime - initTime > timer) {
- initTime = nowTime;
- fn.apply(ctx, args);
- }
- };
- }
- const positionReset = () => {
- const dragDom = document.getElementsByClassName(
- props.domClassName ? props.domClassName : 'drag-container'
- )[0] as HTMLElement;
- data.startPosition = {
- left: '',
- top: '',
- cssText: ''
- };
- dragDom.style.left = data.startPosition?.left;
- dragDom.style.top = data.startPosition?.top;
- dragDom.style.cssText = data.startPosition?.cssText;
- };
- ctx.expose({
- positionReset
- });
- return {
- ...toRefs(data),
- throttle
- };
- }
- });
- </script>
- <style lang="scss" scoped>
- @import url('../../styles/common.scss');
- @import url('../../styles/icon.scss');
- .drag-container {
- position: fixed;
- z-index: 100;
- }
- </style>
|