一、最终效果

三、参数配置
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;
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再次封装基础组件文档