useDraggable
适用于 Vue3
、Nuxt3
、HTML
使元素可拖动
示例
基础示例
拖着我满世界跑吧
offsetX: 0 offsetY: 0
点击召回
查看代码
vue
<script setup lang="ts">
import { ref, computed, watch } from "vue";
import { useDraggable } from "@pureadmin/utils";
const targetRef = ref();
const dragRef = ref();
const { dragging, transform, init, reset } = useDraggable(targetRef, dragRef);
// 初始化开启拖动功能
init();
let info = computed(() => {
return `offsetX: ${Math.round(transform.offsetX)} offsetY: ${Math.round(
transform.offsetY
)}`;
});
watch(
() => dragging.value,
val => {
val ? console.log("正在拖动") : console.log("停止拖动");
}
);
</script>
<template>
<div
ref="targetRef"
class="pure-target"
:style="{ zIndex: transform.offsetX === 0 ? 0 : 999 }"
>
<div ref="dragRef" class="pure-drag">
<svg
xmlns="http://www.w3.org/2000/svg"
width="88"
height="88"
viewBox="0 0 1024 1024"
>
<path
fill="#3451b2"
d="M119.026 584.87a43.651 43.651 0 1 0-43.651-43.652 43.651 43.651 0 0 0 43.651 43.652M945.487 45.633a32.01 32.01 0 0 0-58.201-27.064L694.348 465.848a183.917 183.917 0 0 1 58.201 25.026zM645.46 511.245c-51.218 0-68.096 34.048-140.557 89.339a475.215 475.215 0 0 1-254.923 90.794c-85.265 4.365-217.091 0-229.896 12.805s26.191 123.387 127.17 191.483c58.202 38.704 200.214 136.191 332.04 127.752 213.018-13.677 255.505-174.605 268.31-229.896a838.102 838.102 0 0 0 12.804-203.705c-4.365-51.8-55.292-77.117-114.948-77.117zm-12.805 396.061c-119.895 116.403-229.896 63.73-229.896 63.73l138.229-95.159-224.076 58.202-64.021-38.413 171.694-48.89-235.425 10.477-12.804-25.609 160.927-43.07-199.34 17.752-67.223-63.73a1504.51 1504.51 0 0 0 293.626-25.609 478.707 478.707 0 0 0 166.166-76.535l166.165 76.535a207.488 207.488 0 0 1-64.022 191.483zM948.398 584.87a58.202 58.202 0 1 0 58.201 58.201 58.202 58.202 0 0 0-58.201-58.201m-87.303 261.906a29.1 29.1 0 1 0 29.101 29.101 29.1 29.1 0 0 0-29.1-29.1zM308.181 555.77a29.1 29.1 0 1 0-29.1-29.1 29.1 29.1 0 0 0 29.1 29.1"
/>
</svg>
<p>拖着我满世界跑吧</p>
<p>{{ info }}</p>
</div>
<p class="pure-reset" title="复位" @click="reset">点击召回</p>
</div>
</template>
<style scoped>
.pure-target {
position: relative;
width: 15em;
height: 15em;
display: flex;
align-items: center;
overflow: hidden;
justify-content: center;
color: var(--vp-c-brand);
border-radius: 0.5em;
background-color: var(--vp-custom-block-tip-bg);
border: 1px solid var(--vp-custom-block-tip-border);
}
.pure-reset {
cursor: pointer;
position: absolute;
bottom: -10px;
right: 10px;
}
.pure-reset:hover {
color: var(--vp-c-text-1);
}
.pure-drag {
text-align: center;
}
.pure-drag svg {
margin: 0 auto;
}
</style>
可拖动的 naiveui模态框
基础用法
查看代码
vue
<script setup lang="ts">
import { ref } from "vue";
import { useDraggable } from "@pureadmin/utils";
const targetRef = ref();
const dragRef = ref();
let showModal = ref(false);
const { init } = useDraggable(targetRef, dragRef);
function onOpenModal() {
showModal.value = true;
init();
}
</script>
<template>
<naive-theme>
<n-button @click="onOpenModal"> 点击打开模态框 </n-button>
<n-modal v-model:show="showModal">
<div ref="targetRef">
<n-card
style="width: 400px"
title="模态框"
:bordered="false"
size="huge"
role="dialog"
aria-modal="true"
>
<template #header>
<div ref="dragRef">拖动我吧</div>
</template>
emm...不知道写点啥 🤷
</n-card>
</div>
</n-modal>
</naive-theme>
</template>
使用 Dialog 预设
哈哈,你没有看错,就是如此简单
查看代码
vue
<script setup lang="ts">
import { ref } from "vue";
import { useDraggable } from "@pureadmin/utils";
let showModal = ref(false);
const { draggable, init, close, reset, open } = useDraggable(
".n-dialog",
".n-dialog__title"
);
function onOpenDialog() {
showModal.value = true;
init();
}
</script>
<template>
<naive-theme>
<n-button @click="onOpenDialog"> 点击打开模态框 </n-button>
<n-modal v-model:show="showModal" preset="dialog" :maskClosable="false">
<template #header> 拖动我吧 </template>
<div>
<p>naiveui:我暴露了足够的api,怎么会难用呢?🤔</p>
<p>二开疯子:确实,这下很多组件都能更好地二次封装了 😄</p>
<p>拷贝高手:好咧,赶紧动起来!👍</p>
</div>
<template #action>
<n-button @click="reset">复位</n-button>
<n-button @click="close" v-if="draggable">关闭拖动</n-button>
<n-button @click="open" v-else>开启拖动</n-button>
</template>
</n-modal>
</naive-theme>
</template>
最简代码
可拖动的Div
vue
<script setup lang="ts">
import { ref } from "vue";
import { useDraggable } from "@pureadmin/utils";
const targetRef = ref();
const dragRef = ref();
const { init } = useDraggable(targetRef, dragRef);
// 初始化开启拖动功能
init();
</script>
<template>
<div ref="targetRef">
<div ref="dragRef">
<!-- 内容区 -->
</div>
</div>
</template>
API
参数
ts
// 在此处配置参数
const {} = useDraggable(targetRef, dragRef, args);
参数属性 | 必传 | 说明 | 类型 |
---|---|---|---|
targetRef | 是 | 要拖动的元素。可以是获取DOM元素或组件实例引用的ref,也可以是class类名 (如:".target" )或元素ID (如:"#target" ) | Ref<HTMLElement>/string |
dragRef | 是 | 拖动的地方。可以是获取DOM元素或组件实例引用的ref,也可以是class类名 (如:".drag" )或元素ID (如:"#drag" ) | Ref<HTMLElement>/string |
args | 否 | 额外的可选参数,具体看下面的args 详情 | ArgsDraggable |
args
详情
对象格式,拥有下面两个属性
参数属性 | 说明 | 类型 | 默认值 |
---|---|---|---|
dragRefStyle | 为了方便用户识别可拖动的区域,添加额外样式到dragRef 上。可以使用{} 空对象清空默认样式,也可以自定义样式 | CSSProperties | { cursor: "move", userSelect: "none" } |
resize | 当页面resize 时,如果拖动的元素超出新的视口边界,是否将其恢复到初始位置。true :代表恢复到初始位置。false :代表不会恢复到初始位置。当然也可以填写resize 时的防抖延迟时间,默认60 毫秒 | boolean/number | true |
返回值、方法
返回值、方法 | 说明 | 类型 |
---|---|---|
draggable | 是否已经开启拖动功能(响应式)。true 代表已开启拖动功能,false 代表关闭了拖动功能 | Ref<boolean> |
dragging | 是否正在拖动中(响应式)。true 代表正在拖动,false 代表没有拖动 | Ref<boolean> |
transform | 响应式对象transform :包含当前被拖动元素的offsetX 、offsetY 信息 | {offsetX: number;offsetY: number;} |
init | 初始化开启拖动功能 | () => void |
open | 开启拖动功能。常用于当关闭拖动时,想再次开启拖动并在当前所处位置继续拖动 | () => void |
close | 关闭拖动功能 | () => void |
reset | 将拖动元素恢复到初始位置 | () => void |