electron 实践 - 内嵌 webview
- new BrowserWindow 配置开启
ts
import { app, BrowserWindow } from 'electron'
import { electronApp, optimizer } from '@electron-toolkit/utils'
import { ipcMainHandle } from './ipc/handle/index'
import { ipcMainOn } from './ipc/on/index'
import { registerShortcuts, unregisterShortcuts } from './shortcut'
import { registerMainIpc, unregisterMainIpc } from './ipc'
import { createWindow } from '@electron/utils/window'
import { copyFileStream } from '@electron/utils/file'
import { getResourcePath, getUserDataPath } from '@electron/utils/path'
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(async () => {
// Set app user model id for windows
electronApp.setAppUserModelId('com.electron')
// Default open or close DevTools by F12 in development
// and ignore CommandOrControl + R in production.
// see https://github.com/alex8088/electron-toolkit/tree/master/packages/utils
app.on('browser-window-created', (_, window) => {
optimizer.watchWindowShortcuts(window)
})
// 创建浏览器窗口
createWindow()
// ipcMain.on:模块注册(更通用方案)
registerMainIpc()
// ipcMain.on:直接绑定
ipcMainOn()
// ipcMain.handle:直接绑定
ipcMainHandle()
//
registerShortcuts()
app.on('activate', function () {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
await copyFileStream(getResourcePath('raw/shell/update.exe'), getUserDataPath())
})
// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.once('will-quit', async () => {
unregisterMainIpc()
unregisterShortcuts()
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.- vite 配置:webiew 非自定义元素
ts
vue({
template: {
compilerOptions: {
// add electron specific tags
isCustomElement: (tag) => ['webview'].includes(tag)
}
}
})vue组件中
<webview>元素配置,src 配置外部链接,preload 同时注入 <<< @/submodule/play-electron/src/renderer/src/views/webview/index.vue#webviewRef外部链接中
http://.../files/index.html调用electron主进程
js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
body {
background-color: #2b947a;
}
ul {
list-style: none;
}
li{
line-height: 20px;
}
h4 {
padding: 0;
margin: 0;
}
</style>
</head>
<body>
<h4>webview 内嵌内容</h4>
<ul>
<li>
<span>localStorage:</span>
<span id="localStorage"></span>
<button id="getItem" >localStorage get</button>
<button id="setItem">localStorage set</button>
</li>
<li>
<span>isInElectron:</span>
<span id="isInElectron"></span>
</li>
<li>
<span>调用 preload 中的 ping:</span>
<button id="ping">ping</button>
</li>
</ul>
<script>
// 缓存
const getLocalStorage = () => {
const test = document.getElementById('localStorage')
test.innerHTML = `${localStorage.getItem('test')}`
}
getLocalStorage()
const getItem = document.getElementById('getItem')
getItem.addEventListener('click', () => {
getLocalStorage()
})
const setItem = document.getElementById('setItem')
setItem.addEventListener('click', () => {
localStorage.setItem('test', '123')
getLocalStorage()
})
</script>
<script>
const isInElectron = document.getElementById('isInElectron')
isInElectron.innerHTML = window.IS_IN_ELECTRON ? '是(在electron中)' : '否(没有在electron中)'
</script>
<script>
const ping = document.getElementById('ping')
ping.addEventListener('click', () => {
window.electron.ipcRenderer.send('ping')
})
</script>
</body>
</html>