// myPlugin.js export default function myPlugin() { return { name: 'myplugin', enforce: 'pre', transform(code, id) { if (!/\.vue$/.test(id) || !isTargetFile(id)) return // 处理模板 const templateContent = extractTemplateContent(code) const processedTemplate = processTemplate(templateContent) // 处理脚本 const scriptContent = extractScriptContent(code) const processedScript = processScript(scriptContent) // 处理样式 const processedCode = code .replace(regex, processedTemplate) .replace(/(]*>)/, `$1\n${processedScript}`) .replace(/(<\/style>)/, `${targetStyles}\n$1`) //输出代码 console.log(processedCode,1111111) return processedCode }, handleHotUpdate(ctx) { const read = ctx.read if (/\.vue$/.test(ctx.file)) { ctx.read = async () => { const code = await read() return `${code}` } } } } } const regex = /([\s\S]*?)/ // 模板处理逻辑 function processTemplate(template) { let rowIndex = 0 return template .replace(/ { rowIndex++ return `${match} data-auto-row="${rowIndex}"` }) .replace(/]*)>/g, (match, attrs) => { const uniqueSuffix = Math.random().toString(36).substr(2, 6) const uid = `__auto_${rowIndex}_${uniqueSuffix}` return `
`.trim().replace(/\n\s+/g, ' ') }) .replace(/<\/el-col>/g, '
') } // 脚本处理逻辑 function processScript(script) { const autoScript = ` // AUTO-INJECTED DRAG LOGIC const __autoDragElement = ref(null) const __autoDropInfo = ref({ targetId: null, direction: null }) const __autoDragStart = (e, id) => { __autoDragElement.value = id e.dataTransfer.effectAllowed = 'move' } const __autoDragOver = (e, targetId) => { e.preventDefault() const rect = e.currentTarget.getBoundingClientRect() __autoDropInfo.value = { targetId, direction: e.clientX - rect.left < rect.width / 2 ? 'left' : 'right' } } const __autoDragLeave = () => { __autoDropInfo.value = { targetId: null, direction: null } } const __autoDragDrop = (e, targetId) => { e.preventDefault() if (!__autoDragElement.value || !targetId) return console.log(\`DRAG_ACTION: \${__autoDragElement.value} -> \${targetId} (\${__autoDropInfo.value.direction})\`) __autoDragElement.value = null __autoDropInfo.value = { targetId: null, direction: null } } `.trim() return script.includes('ref') ? autoScript : `import { ref } from 'vue'\n${autoScript}` } // 辅助函数 function isTargetFile(id) { return id === 'D:/workspace/RuoYi-Vue/ruoyi-ui/src/views/index.vue' } function extractTemplateContent(code) { const match = code.match(regex) return match ? match[1] : '' } function extractScriptContent(code) { const scriptMatch = code.match(/]*>([\s\S]*?)<\/script>/) return scriptMatch ? scriptMatch[1] : '' } // 样式配置(保持原样) //样式 const targetStyles = `.grid-content { border: 1px solid #e4e7ed; min-height: 36px; display: flex; align-items: center; justify-content: center; padding: 20px; transition: all 0.3s ease; position: relative; cursor: move; user-select: none; background: white; z-index: 1; /* 悬停效果 */ &:hover { background-color: #f5f7fa; border-color: #409eff; transform: translateY(-2px); z-index: 2; box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1); } /* 拖放指示器 */ .drop-hint { position: absolute; top: 0; height: 100%; width: 50%; z-index: 3; pointer-events: none; &::after { position: absolute; top: 50%; transform: translateY(-50%); font-size: 12px; color: #409eff; font-weight: 500; padding: 4px 8px; background: rgba(255, 255, 255, 0.9); border-radius: 4px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); } /* 左侧指示 */ &.left { left: 0; border-left: 3px solid #409eff; &::after { content: "← 放置左侧"; left: 10px; } } /* 右侧指示 */ &.right { right: 0; border-right: 3px solid #409eff; &::after { content: "放置右侧 →"; right: 10px; } } } /* 拖放时的半透明效果 */ &[draggable="true"]:active { opacity: 0.8; transform: scale(0.98); } /* 当前拖拽元素的样式 */ &.drag-overlay { opacity: 0.5; transform: rotate(3deg); } } /* 行间距 */ .el-row { margin-bottom: 20px; &:last-child { margin-bottom: 0; } } /* 拖放过程的状态指示 */ .drag-enter { background: linear-gradient( 45deg, rgba(64, 158, 255, 0.1) 25%, transparent 25%, transparent 50%, rgba(64, 158, 255, 0.1) 50%, rgba(64, 158, 255, 0.1) 75%, transparent 75%, transparent ); background-size: 40px 40px; animation: dragStripes 3s linear infinite; } @keyframes dragStripes { 0% { background-position: 0 0; } 100% { background-position: 40px 0; } } /* 优化移动端触摸体验 */ @media (hover: none) { .grid-content { touch-action: manipulation; &:active { transform: scale(0.96); } } }`;