最近一直在做编辑器
的小项目,怎么说呢?一个看起来非常简单的小工具也需要大量的巧思和优化。
其实我发现随随便便的一个小工具都有重新做一遍的价值,一来是符合新的使用习惯,二来新的UI风格也更顺眼。
现在AI编程真的是"害人不浅",比较难的功能随手Trea一下,直接代码就写好了,这简直是程序员的"盛夏"。

做编辑器
的过程中发现一个复制的功能,放在工具栏需要两步操作,点击工具
,然后再点击复制到哪个平台
。
还是放出来比较合适,但是放在外层又有点儿遮挡,所以做了一个可以拖拽的工具栏。
源码
html
<template>
<div class="tool-copy-container" :style="toolPosition">
<!-- 拖拽部分 -->
<div class="tool-copy-drag" @mousedown="startDragging">
<i class="iconfont icon-drag"></i>
</div>
<div class="tool-copy-item" v-for="(item, index) in tools" :key="index">
<el-tooltip
class="box-item"
effect="dark"
:content="'复制到' + item.name"
placement="left"
>
<i class="iconfont" :class="item.icon" :style="{color: item.color}"></i>
</el-tooltip>
</div>
</div>
</template>
<script setup>
import { reactive, ref } from "vue";
// 工具列表数据
const tools = reactive([
{
name: '公众号',
title: 'wechat',
icon: 'icon-wechat',
color: '#07C874'
},
......
]);
// 初始位置
const toolPosition = reactive({
top: '300px',
right: '20px'
});
// 拖拽相关状态
// 定义一个响应式的布尔变量,用于追踪是否正在拖动
const isDragging = ref(false);
// 定义一个响应式的对象,用于存储拖动偏移量
const dragOffset = reactive({
x: 0,
y: 0
});
/**
* 开始拖动的函数
* @param {MouseEvent} event - 触发的鼠标事件
*/
function startDragging(event) {
isDragging.value = true;
// 获取目标元素的位置信息
const rect = event.target.getBoundingClientRect();
// 计算鼠标点击位置相对于元素左上角的偏移量
dragOffset.x = event.clientX - rect.left;
dragOffset.y = event.clientY - rect.top;
// 添加鼠标移动和释放事件监听器
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
}
/**
* 鼠标移动时的处理函数
* @param {MouseEvent} event - 触发的鼠标事件
*/
function onMouseMove(event) {
if (!isDragging.value) return;
// 计算新的鼠标位置,并减去初始偏移量
const x = event.clientX - dragOffset.x;
const y = event.clientY - dragOffset.y;
// 设置新的位置
toolPosition.top = `${y}px`;
toolPosition.right = `${window.innerWidth - (x + rect().width)}px`;
// 禁止文本选择,防止用户在拖动时选择页面内容
document.body.style.userSelect = 'none';
}
/**
* 鼠标释放时的处理函数
*/
function onMouseUp() {
isDragging.value = false;
// 移除鼠标移动和释放事件监听器
document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('mouseup', onMouseUp);
// 恢复文本选择,允许用户选择页面内容
document.body.style.userSelect = '';
}
/**
* 获取工具容器的尺寸信息
* @returns {DOMRect} - 元素的尺寸信息,如果没有找到元素则返回 { width: 0 }
*/
function rect() {
const el = document.querySelector('.tool-copy-container');
return el ? el.getBoundingClientRect() : { width: 0 };
}
</script>
<style scoped>
.tool-copy-container {
background-color: #fff;
border: 1px solid #ddd;
position: fixed;
top: 50%;
right: 20px;
}
.tool-copy-drag {
width: 100%;
text-align: center;
cursor: all-scroll;
}
.tool-copy-item {
margin: 5px 0;
text-align: center;
padding: 0 5px;
box-sizing: border-box;
cursor: pointer;
}
</style>
原理
给要移动的DOM一个动态的style,通过绑定mousedown事件来触发拖动。
通过绑定mousemove事件来实时更新DOM位置,通过mouseup事件来结束拖动。
当然,这只是一个Demo,如果想要更好的效果还需要再优化。
Ps: 后期会把做的编辑器开源,希望大家捧场。万分感谢!