一、最終效果
二、具體詳情請看movable-area與movable-view官方文檔說明
三、參數配置
1、代碼示例
<TFab title="新建訂單" @click="addOrder" />
// title:表按鈕文案
// addOrder:點擊按鈕事件
四、組件源碼
<template><movable-area class="movable-area" @touchend="onTouchend"><movable-view class="movable-view" :x="x" :y="y" direction="all" @change="onChange"><view class="addBtn" :style="{ width: `${width}px` , height: `${height}px`}" @tap="handleClick">{{title}}</view><slot /></movable-view></movable-area>
</template><script lang="ts" setup>
import { debounce } from "@/utils";
defineProps({title: {type: String},width: {type: Number,default: 40},height: {type: Number,default: 40}
});
const emits = defineEmits(["click"]);
const x = ref(0);
const y = ref(0);
const screenWidth = ref(0);
const screenHeight = ref(0);onMounted(() => {uni.getSystemInfo({success: res => {screenWidth.value = res.windowWidth;screenHeight.value = res.windowHeight;// 初始位置在屏幕右下角y.value = screenHeight.value - 200;x.value = screenWidth.value - 70;}});
});
// 拖動坐標更新(防抖)
const onChange = (e: { detail: { x: number; y: number } }) => {debounce(() => {x.value = e.detail.x;y.value = e.detail.y;}, 500);
};
// 觸摸結束時吸附邊緣
const onTouchend = () => {nextTick(() => {const threshold = 50; // 吸附閾值(rpx)if (Math.abs(x.value - 0) < threshold) {x.value = 0;} else if (Math.abs(x.value - screenWidth.value) < threshold) {x.value = screenWidth.value;}if (Math.abs(y.value - 0) < threshold) {y.value = 0;} else if (Math.abs(y.value - screenHeight.value) < threshold) {y.value = screenHeight.value;}});
};
const handleClick = () => {emits("click");
};
</script><style lang="scss">
.movable-area {position: fixed;top: 0;left: 0;width: 100vw;height: calc(100vh - 100px); // 可根據自己的項目來計算pointer-events: none; /* 關鍵樣式 */z-index: 9999;.movable-view {pointer-events: auto; /* 關鍵樣式 */width: 100rpx;height: 100rpx;will-change: transform;.addBtn {border-radius: 50%;width: 40px;height: 40px;overflow: hidden;display: flex;justify-content: center;align-items: center;color: #fff;font-size: 14px;padding: 8px;box-shadow: 0 1px 5px 2px rgba(0, 0, 0, 0.3);background: #355db4;text-align: center;}}
}
</style>
相關文章
基于ElementUi再次封裝基礎組件文檔
vue3+ts基于Element-plus再次封裝基礎組件文檔