vue3 实现右键菜单编辑复制粘贴功能
vue3编辑器在浏览器有默认的右键菜单,但是在客户端electron中要实现这个右键菜单的功能需要手写。
代码如下
template !-- 右键菜单 -- div div v-if="menuVisible" @mousedown.prevent class="custom-menu" :style="{ top: menuY + 'px', left: menuX + 'px' }" ul li @click="copyText" 复制 /li li @click="cutText" 剪切 /li li @click="pasteText" 粘贴 /li /ul /div div id="vditor" @contextmenu.prevent="showMenu" /div /div /template
script setup // 安装插件vditorimport Vditor from "vditor";import "vditor/dist/index.css";import { ref, onMounted } from "vue";onMounted(() = { document.addEventListener("click", hideMenu); // 初始化全局点击事件,隐藏右键菜单 initVditor();});const vditor = ref(null); // 使用 ref 来存储 vditor 实例const initVditor = () = { if (vditor.value) { vditor.value.setValue("你好,这是测试"); } else { console.log("初始化macket", import.meta.env.MODE); vditor.value = new Vditor("vditor", { width: "100%", cdn: import.meta.env.MODE === "development" ? "./public" : "./", placeholder: "请输入内容...", toolbar: [], preview: { markdown: { sanitize: false, }, }, after() { vditor.value.setValue("你好,这是测试"); // 一次性设置所有内容,并移除开头的多余空格 }, input(value) { const markdownContent = vditor.value.getValue(); }, }); }};// 用于控制右键菜单的显示和位置const menuVisible = ref(false);const menuX = ref(0);const menuY = ref(0);const copiedText = ref(""); // 用于保存复制或剪切的文本let lastFocusedElement = null; // 用于保存最后聚焦的元素const fuzhitext = ref("");// 显示右键菜单function showMenu(event) { copiedText.value = vditor.value.getSelection(); menuVisible.value = true; menuX.value = event.clientX; menuY.value = event.clientY; document.addEventListener("click", hideMenu); // 点击其他地方隐藏菜单 // 保存当前聚焦的元素 lastFocusedElement = document.activeElement; console.log(lastFocusedElement);}// 隐藏右键菜单function hideMenu() { menuVisible.value = false; // document.removeEventListener('click', hideMenu);}// 复制选中的文本function copyText() { if (copiedText.value) { console.log("复制的内容:", copiedText.value); fuzhitext.value = copiedText.value; } else { console.log("没有选中的文本"); } // 延迟聚焦以保持选中状态 setTimeout(() = { vditor.value.focus(); }, 0); vditor.value.updateValue(copiedText.value); hideMenu();}// 粘贴文本function pasteText() { if (fuzhitext.value) { vditor.value.deleteValue(); // 这里你可以使用插入内容的API来粘贴文本 vditor.value.insertValue(fuzhitext.value); } setTimeout(() = { lastFocusedElement.focus(); }, 0); hideMenu();}// 剪切function cutText() { if (copiedText.value) { console.log("复制的内容:", copiedText.value); fuzhitext.value = copiedText.value; } else { console.log("没有选中的文本"); } vditor.value.deleteValue(); setTimeout(() = { lastFocusedElement.focus(); }, 0); hideMenu();} /script style scoped .custom-menu { position: absolute; background-color: white; border: 1px solid #ccc; border-radius: 10px; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); z-index: 1000; animation: slideDown 0.2s ease-in-out; /* 添加下拉动画 */}.custom-menu ul { list-style-type: none; padding: 0; /* 移除内边距 */ margin: 0; /* 移除外边距 */ min-width: 95px;}.custom-menu ul li { padding: 8px 30px; /* 增加上下内边距 */ cursor: pointer; transition: background-color 0.2s; /* 添加背景色过渡效果 */}.custom-menu ul li:hover { background-color: #e9f5ff; /* 悬停时背景色变化 */ border-radius: 10px;}/* 下拉动画 */@keyframes slideDown { from { opacity: 0; transform: translateY(-10px); /* 初始位置稍微上移 */ } to { opacity: 1; transform: translateY(0); }} /style
vue3 实现右键菜单编辑复制粘贴功能