创建无边框窗口 main/index.js
const mainWindow = new BrowserWindow({
width: 100,
height: 30,
show: true,
frame: false, //边框
thickFrame: false, //阴影
titleBarStyle: 'hidden', // 隐藏标题栏
transparent: true, //透明
alwaysOnTop: true, //置顶
resizable: false, //调大小
autoHideMenuBar: true, //隐藏菜单栏
webPreferences: {
preload: join(__dirname, '../preload/index.js'),
sandbox: false
}
})
监听渲染层鼠标事件
let XY = {
//鼠标与窗口定位差值
x: 0,
y: 0
}
let currentWindow = null //当前窗口
let IntervalId = null //定时器id
// 移动窗口----start
ipcMain.on('winMove-start', (event) => {
currentWindow = BrowserWindow.fromWebContents(event.sender)
const winPosition = currentWindow.getPosition()
const cursorPosition = screen.getCursorScreenPoint() //开始时鼠标位置
XY.x = cursorPosition.x - winPosition[0]
XY.y = cursorPosition.y - winPosition[1]
clearInterval(IntervalId)
IntervalId = setInterval(() => {
refreshWinPosition()
}, 20)
})
// 移动窗口----end
ipcMain.on('winMove-end', (event, params) => {
clearInterval(IntervalId)
})
function refreshWinPosition() {
const cursorPosition = screen.getCursorScreenPoint() //移动后鼠标位置
currentWindow.setPosition(cursorPosition.x - XY.x, cursorPosition.y - XY.y, true) //设置窗口位置
}
预加载器preload/index.js
import { contextBridge, ipcMain } from 'electron'
import { electronAPI } from '@electron-toolkit/preload'//我用的electron-vite模版自带的
contextBridge.exposeInMainWorld('electron', electronAPI)//用于渲染层暴露electronAPI
渲染层编写(vue3)
自定义拖动指令v-dropWindow
src/directive/dropWindow/index.js
const { ipcRenderer } = window.electron
const dropWindow = {
mounted(el, binding, vnode) {
//按下鼠标左键
el.addEventListener('mousedown', (e) => {
if (e.buttons == 1) {
winMoveStart() //开始刷新屏幕位置
el.addEventListener('mousemove', mousemove)
}
})
//按下松开鼠标鼠标
el.addEventListener('mouseup', () => {
winMoveEnd() //停止刷新屏幕位置
el.removeEventListener('mousemove', mousemove)
})
function winMoveStart() {
ipcRenderer.send('winMove-start')
}
//补丁:鼠标在窗口外松开不触发mouseup,鼠标回到窗口没按着左键停止
function mousemove(e) {
if (e.buttons != 1) {
winMoveEnd()
el.removeEventListener('mousemove', mousemove)
}
}
function winMoveEnd() {
ipcRenderer.send('winMove-end')
}
}
}
export default dropWindow
批量注册指令插件 src/directive/index.js
// 导入指令定义文件
import dropWindow from './dropWindow'
// 集成一起
const directives = {
dropWindow
}
//批量注册
directives.install = function (app) {
Object.keys(directives).forEach((key) => {
app.directive(key, directives[key])
})
}
export default directives
使用插件 src/main.js
import { createApp } from 'vue'
import App from './App.vue'
import directives from './directive'
createApp(App).use(directives).mount('#app')
页面使用
在可以拖动的节点添加自定义指令v-dropWindow
<div class="Xpage" v-dropWindow>
<div class="flex-xy-b color-a cell fs-12" v-for="stock in stocks" key="code">
<div>{{ stock.now }}</div>
<div>{{ +(+stock.percent * 100).toFixed(2) }}%</div>
</div>
</div>