我用的vue2
vue create qq_test
npm install electron -g
//or
npm install [email protected] //老版本
版本我选择的是12
vue add electron-builder
background.js里面有默认的配置,修改后我的配置大概如下
'use strict'
import { app, protocol, BrowserWindow, Menu, Tray } from 'electron'
import { createProtocol } from 'vue-cli-plugin-electron-builder/lib'
import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer'
const isDevelopment = process.env.NODE_ENV !== 'production'
// Scheme must be registered before the app is ready
protocol.registerSchemesAsPrivileged([
{ scheme: 'app', privileges: { secure: true, standard: true } }
])
async function createWindow() {
// Create the browser window.
const win = new BrowserWindow({
width: 432,
height: 331,
alwaysOnTop: true,//窗口一直保持在其他窗口前面
modal: true,
frame: false,
darkTheme: true,
resizable: false,//用户不可以调整窗口
center: true, // 窗口居中
transparent: false,//窗口透明
show: false,// 显示窗口将没有视觉闪烁(配合下面的ready-to-show事件)
hasShadow: true,//窗口是否有阴影
webPreferences: {
// Use pluginOptions.nodeIntegration, leave this alone
// See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info
// nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,
// contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION,
devTools: true,//客户端可以打开开发者工具(在客户端打开快捷键:ctrl+shift+i)
nodeIntegration: true,
enableRemoteModule: true, // 使用remote模块(electron12版本就开始废除了,需要我们自己安装remote模块)
contextIsolation: false,
//解决axios请求跨域问题(不推荐,不安全,但简单好用)
webSecurity: false,
},
})
if (process.env.WEBPACK_DEV_SERVER_URL) {
// Load the url of the dev server if in development mode
await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
if (!process.env.IS_TEST) win.webContents.openDevTools()
} else {
createProtocol('app')
// Load the index.html when not in development
win.loadURL('app://./index.html')
}
}
// Quit when all windows are closed.
app.on('window-all-closed', () => {
// On macOS it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
// 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()
})
// 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.once('ready-to-show', () => {
win.show();
})
app.on('ready', async () => {
if (isDevelopment && !process.env.IS_TEST) {
// Install Vue Devtools
try {
await installExtension(VUEJS_DEVTOOLS)
} catch (e) {
console.error('Vue Devtools failed to install:', e.toString())
}
}
createWindow()
})
// Exit cleanly on request from parent process in development mode.
if (isDevelopment) {
if (process.platform === 'win32') {
process.on('message', (data) => {
if (data === 'graceful-exit') {
app.quit()
}
})
} else {
process.on('SIGTERM', () => {
app.quit()
})
}
}
因为electron12版本开始就废除了remote模块,我们需要自己安装
npm install @electron/remote --save
//or
cnpm install @electron/remote --save
能在客户端实现 最大化、最小化、关闭功能
1、Login.vue页面(登录页面)
里面的最小化图标、关闭图标、最大化图标 请自己去 iconfont-阿里巴巴矢量图标库 下载
2、login.css
/**
取消全部的外边距和内边距
*/
* {
padding: 0;
margin: 0;
}
/*设置窗口的样式*/
.login {
cursor: default;
/*设置手型*/
/* border: 1px solid red; */
/*加一个边框 调试样式 最后要删除或者更改**/
width: 430px;
/*设置宽度 必须要和主进程中设置的一样 不能大于主进程中设置的宽度 否则会出现滚动条*/
height: 329px;
/*设置高度 必须要和主进程中设置的一样 不能大于主进程中设置的高度 否则会出现滚动条*/
position: relative;
/*设置为相对定位*/
/* border-radius: 4px; */
/*设置圆角*/
border: 1px solid #464545;
/* 拖 */
-webkit-app-region: drag;
/* 禁止滚动条 */
overflow: hidden;
}
/**
header的样式 header中只会有一个关闭按钮 处于右上角
*/
.login header.header {
position: absolute;
/*设置绝对定位 因为背景在他下面*/
height: 30px;
/*设置高度*/
/* border-radius: 20px 20px 0 0; */
/*给header的左上角 右上角设置圆角 不然会出现很尴尬的页面*/
width: 428px;
/* 因为设置了绝对定位 设置宽度*/
/* background: rgba(255, 255, 255, 0.2); */
/*暂时设置的 后面要删除或者更改*/
text-align: right;
}
/**
背景
*/
.login main .bg {
height: 124px;
/*设置高度*/
width: 430px;
/*设置宽度 也可以不用设置 因为这个元素没有设置绝对定位 所以默认就是100%*/
/* border-radius: 4px 4px 0 0; */
/*给左上角 右上角设置圆角 不然会出现很尴尬的页面 这里和header重合在一起了*/
/* background: url("@/assets/images/login.gif") 10px; */
background-size: 100%;
}
/**
放置表单的元素
*/
.login main .body {
width: 428px;
/*设置宽度 也可以不用设置 因为这个元素没有设置绝对定位 所以默认就是100%*/
height: 200px;
/*设置高度 这里的高度是 主窗口(326) - footer(30) - 背景(124) 因为header设置了绝对定位 所以不用关 */
/* background: green; */
/*暂时设置的 后面要删除或者更改*/
}
.login footer.footer {
position: absolute;
/* 设置绝对定位 要让他处于窗口的最底部*/
height: 30px;
/*设置高度 */
/* background: red; */
/*暂时设置的 后面要删除或者更改*/
bottom: 0;
/*让footer处于底部*/
width: 397.99px;
/* 因为设置了绝对定位 设置宽度*/
/* border-radius: 0 0 5px 5px; */
background-color: #FFFFFF;
}
.login header.header span{
display: inline-block;
height: 30px;
width:30px;
text-align: center;
line-height: 30px;
color:#E4393c;
cursor: pointer;
}
.login header.header span:hover{
background-color: rgba(255,255,255,0.6);
cursor: pointer;
}
.zczh{
cursor: pointer;
color: #7c7a7a;
user-select: none;
-webkit-app-region: no-drag;
}
.zczh:hover{
cursor: pointer;
color: black;
user-select: none;
-webkit-app-region: no-drag;
}
3、Login_form.vue组件
里面的resetMessage信息提示是我重新封装的element组件(我就不放上去了)
里面的最小化图标、关闭图标、最大化图标 请自己去 iconfont-阿里巴巴矢量图标库 下载
4、login_form.css
.login_form{
-webkit-app-region: drag;
background-color: #FFFFFF;
}
.login_form form {
padding: 10px 90px 0 90px;
}
.form_item {
height: 40px;
position: relative;
}
.form_item div {
float: right;
margin-right: 5px;
}
.form_item i.iconfont {
position: absolute;
top: 5px;
}
.form_item input {
outline: none;
border: none;
padding-left: 30px;
font-size: 16px;
width: 230px;
height: 30px;
border-bottom: 1px solid #CCC;
user-select: none;
-webkit-app-region: no-drag;
}
.buttons {
text-align: center;
}
.buttons button {
background-color: #0786b4;
border: none;
width: 250px;
color: #FFFFFF;
height: 35px;
cursor: pointer;
font-size: 14px;
border-radius: 4px;
outline: none;
-webkit-app-region: no-drag;
user-select: none;
}
.buttons button:hover {
background-color: #0aaae4;
border: none;
width: 250px;
color: #FFFFFF;
height: 35px;
cursor: pointer;
font-size: 14px;
border-radius: 4px;
outline: none;
-webkit-app-region: no-drag;
user-select: none;
}
.checkbox {
display: flex;
justify-content: center;
align-items: center;
}
.footer {
display: flex;
justify-content: space-between;
padding: 5px 15px 5px 15px;
align-items: center;
}
.login_options {
margin-bottom: 10px;
margin-top: 5px;
}
.login_options .option_item {
display: inline-block;
align-items: center;
width: 13px;
height: 13px;
margin-right: 5px;
position: relative;
cursor: pointer;
top: 2px;
-webkit-app-region: no-drag;
}
.login_options .option_item input {
/* font-size: 13px; */
-webkit-app-region: no-drag;
}
.login_options i.text {
display: inline-block;
margin-right: 14px;
font-size: 13px;
font-style: normal;
user-select: none;
-webkit-app-region: no-drag;
}
.login_options .option_item span.checked {
position: absolute;
top: -4px;
right: -3px;
font-weight: bold;
display: inline-block;
width: 20px;
height: 20px;
cursor: pointer;
}
.option_item span.checked img {
width: 100%;
height: 100%;
}
input[type="checkbox"]+span {
opacity: 0;
}
input[type="checkbox"]:checked+span {
opacity: 1;
}
.wjmm {
cursor: pointer;
color: rgb(139, 134, 134);
}
.wjmm:hover {
cursor: pointer;
color: rgb(19, 18, 18);
}
5、package.json文件
{
"name": "qq_test",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"electron:build": "vue-cli-service electron:build",
"electron:serve": "vue-cli-service electron:serve",
"postinstall": "electron-builder install-app-deps",
"postuninstall": "electron-builder install-app-deps"
},
"main": "background.js",
"dependencies": {
"axios": "^0.27.2",
"core-js": "^3.8.3",
"element-ui": "^2.15.9",
"express": "^4.18.1",
"qs": "^6.11.0",
"socket.io": "^4.5.1",
"socket.io-client": "^3.1.0",
"vscode-material-icon-theme-js": "^1.0.7",
"vue": "^2.6.14",
"vue-router": "^3.5.1",
"vue-socket.io": "^3.0.10",
"vuex": "^3.6.2"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-plugin-router": "~5.0.0",
"@vue/cli-plugin-vuex": "~5.0.0",
"@vue/cli-service": "~5.0.0",
"electron": "^12.0.0",
"electron-devtools-installer": "^3.1.0",
"sass": "^1.32.7",
"sass-loader": "^12.0.0",
"vue-cli-plugin-electron-builder": "~2.1.1",
"vue-template-compiler": "^2.6.14"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}
6、main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import axios from "axios"; //引入axios
Vue.prototype.$axios = axios; //axios跟很多第三方模块不同的一点是它不能直接使用use方法,而是用这种方法
//配合文章第4步解释 本地网站
axios.defaults.baseURL = 'http://www.electron.com/index.php/api';//开发环境
//引入element组件
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
//重写提示框只提示一次
import resetMessage from '@/assets/js/resetMessage'
Vue.prototype.$resetMessage = resetMessage
Vue.use(
new VueSocketIO({
debug: false,
// 宝塔 IP:端口号 (生产环境)
connection: SocketIO('http://127.0.0.1:3000', {//开发环境
autoConnect: false // 取消自动连接
}),
extraHeaders: { 'Access-Control-Allow-Origin': '*' }
})
)
//客户端禁止按鼠标返回键返回上一个路由
window.addEventListener('popstate', function() {
history.pushState(null, null, document.URL)
})
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
本地测试
npm run electron:serve