electron?vue?模仿qq登錄界面功能實(shí)現(xiàn)
1、使用vuecli創(chuàng)建vue項(xiàng)目
我用的vue2
vue create qq_test
2、安裝electron
npm install electron -g //or npm install electron@12.0.11 //老版本
3、vue項(xiàng)目安裝Electron-builder打包工具
版本我選擇的是12
vue add electron-builder
4、在vue項(xiàng)目的src下有個(gè)background.js文件
background.js里面有默認(rèn)的配置,修改后我的配置大概如下
'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,//用戶不可以調(diào)整窗口
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,//客戶端可以打開開發(fā)者工具(在客戶端打開快捷鍵: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()
})
}
}5、安裝remote模塊
因?yàn)閑lectron12版本開始就廢除了remote模塊,我們需要自己安裝
npm install @electron/remote --save //or cnpm install @electron/remote --save
能在客戶端實(shí)現(xiàn) 最大化、最小化、關(guān)閉功能
6、代碼
1、Login.vue頁面(登錄頁面)
里面的最小化圖標(biāo)、關(guān)閉圖標(biāo)、最大化圖標(biāo) 請自己去 iconfont-阿里巴巴矢量圖標(biāo)庫 下載
<template>
<div class="login" style="overflow:hidden;">
<!-- 頂部 -->
<header class="header">
<!-- 最小化按鈕 -->
<span @click="minwin" class="iconfont icon-24gl-minimization"></span>
<!-- 關(guān)閉按鈕 -->
<span @click="close" class="iconfont icon-guanbi"></span>
</header>
<main>
<!-- 頂部背景圖 -->
<div class="bg">
<img style="" src="../../assets/images/login.gif" />
</div>
<!-- 登錄表單組件 -->
<div class="body">
<Login_form></Login_form>
</div>
</main>
<footer class="footer">
<div class="zczh" @click="zc">注冊賬號</div>
<div>
<span title="二維碼登錄" class="iconfont icon-erweima"></span>
</div>
</footer>
</div>
</template>
<script>
import "@/assets/css/login.css";
import "@/assets/fonts/gb/iconfont.css";
import "@/assets/fonts/zxh/iconfont.css";
import "@/assets/fonts/ewm/iconfont.css";
import Login_form from "@/components/Login_form.vue";
//網(wǎng)頁測試要關(guān)閉,打包成軟件要啟動
const { remote } = window.require("electron");
export default {
name: "login",
data() {
return {};
},
components: {
Login_form,
},
methods: {
close() {
// 只是關(guān)閉窗口,軟件不退出
// remote.getCurrentWindow().hide()
// 關(guān)閉窗口,退出軟件
remote.getCurrentWindow().close();
},
// 最小化
minwin() {
// 最小化,在任務(wù)欄顯示
remote.getCurrentWindow().minimize()
// 隱藏窗口,任務(wù)欄也隱藏
// remote.getCurrentWindow().hide();
},
zc() {
this.$router.push("/reg");
},
},
mounted() {
//顯示窗口
remote.getCurrentWindow().show();
},
};
</script>
<style lang="scss" scpoed>
.login {
max-width: 900px;
overflow: hidden;
min-width: 430px;
.bg {
img {
width: 430px;
height: 124px;
object-fit: cover;
}
}
}
</style>2、login.css
/**
取消全部的外邊距和內(nèi)邊距
*/
* {
padding: 0;
margin: 0;
}
/*設(shè)置窗口的樣式*/
.login {
cursor: default;
/*設(shè)置手型*/
/* border: 1px solid red; */
/*加一個(gè)邊框 調(diào)試樣式 最后要刪除或者更改**/
width: 430px;
/*設(shè)置寬度 必須要和主進(jìn)程中設(shè)置的一樣 不能大于主進(jìn)程中設(shè)置的寬度 否則會出現(xiàn)滾動條*/
height: 329px;
/*設(shè)置高度 必須要和主進(jìn)程中設(shè)置的一樣 不能大于主進(jìn)程中設(shè)置的高度 否則會出現(xiàn)滾動條*/
position: relative;
/*設(shè)置為相對定位*/
/* border-radius: 4px; */
/*設(shè)置圓角*/
border: 1px solid #464545;
/* 拖 */
-webkit-app-region: drag;
/* 禁止?jié)L動條 */
overflow: hidden;
}
/**
header的樣式 header中只會有一個(gè)關(guān)閉按鈕 處于右上角
*/
.login header.header {
position: absolute;
/*設(shè)置絕對定位 因?yàn)楸尘霸谒旅?/
height: 30px;
/*設(shè)置高度*/
/* border-radius: 20px 20px 0 0; */
/*給header的左上角 右上角設(shè)置圓角 不然會出現(xiàn)很尷尬的頁面*/
width: 428px;
/* 因?yàn)樵O(shè)置了絕對定位 設(shè)置寬度*/
/* background: rgba(255, 255, 255, 0.2); */
/*暫時(shí)設(shè)置的 后面要刪除或者更改*/
text-align: right;
}
/**
背景
*/
.login main .bg {
height: 124px;
/*設(shè)置高度*/
width: 430px;
/*設(shè)置寬度 也可以不用設(shè)置 因?yàn)檫@個(gè)元素沒有設(shè)置絕對定位 所以默認(rèn)就是100%*/
/* border-radius: 4px 4px 0 0; */
/*給左上角 右上角設(shè)置圓角 不然會出現(xiàn)很尷尬的頁面 這里和header重合在一起了*/
/* background: url("@/assets/images/login.gif") 10px; */
background-size: 100%;
}
/**
放置表單的元素
*/
.login main .body {
width: 428px;
/*設(shè)置寬度 也可以不用設(shè)置 因?yàn)檫@個(gè)元素沒有設(shè)置絕對定位 所以默認(rèn)就是100%*/
height: 200px;
/*設(shè)置高度 這里的高度是 主窗口(326) - footer(30) - 背景(124) 因?yàn)閔eader設(shè)置了絕對定位 所以不用關(guān) */
/* background: green; */
/*暫時(shí)設(shè)置的 后面要刪除或者更改*/
}
.login footer.footer {
position: absolute;
/* 設(shè)置絕對定位 要讓他處于窗口的最底部*/
height: 30px;
/*設(shè)置高度 */
/* background: red; */
/*暫時(shí)設(shè)置的 后面要刪除或者更改*/
bottom: 0;
/*讓footer處于底部*/
width: 397.99px;
/* 因?yàn)樵O(shè)置了絕對定位 設(shè)置寬度*/
/* 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組件(我就不放上去了)
里面的最小化圖標(biāo)、關(guān)閉圖標(biāo)、最大化圖標(biāo) 請自己去 iconfont-阿里巴巴矢量圖標(biāo)庫 下載
<template>
<div class="login_form">
<form>
<div class="form_item">
<i class="iconfont icon-zhanghao"></i
><input
@focus="i1_get"
@blur="i1_lose"
@input="input1($event)"
id="text"
v-model="email"
type="email"
:placeholder="placeholder1"
@keyup.enter="login"
/>
</div>
<div class="form_item">
<i class="iconfont icon-mima"></i
><input
@focus="i2_get"
@blur="i2_lose"
id="text2"
v-model="password"
type="password"
:placeholder="placeholder2"
@keyup.enter="login"
/>
</div>
<div class="login_options">
<label
><div class="option_item">
<input
:disabled="jzmm"
v-model="zddl"
type="checkbox"
autocomplete="off"
/>
</div>
<i class="text">記住賬號</i></label
>
<label
><div class="option_item">
<input
@click="jzmm_mm"
v-model="jzmm"
type="checkbox"
autocomplete="off"
/>
</div>
<i class="text">記住密碼</i></label
>
<i class="text wjmm">忘記密碼</i>
</div>
</form>
<div class="buttons">
<button @click="login">登錄</button>
</div>
</div>
</template>
<script>
import "@/assets/css/login_form.css";
import "@/assets/fonts/xlk/iconfont.css";
import "@/assets/fonts/slk/iconfont.css";
import "@/assets/fonts/zh/iconfont.css";
import "@/assets/fonts/mm/iconfont.css";
//網(wǎng)頁測試要關(guān)閉,打包成軟件要啟動
const { remote } = window.require("electron");
export default {
name: "Login_form",
data() {
return {
email: "",
password: "",
placeholder1: "郵箱",
placeholder2: "密碼",
zddl: false,
jzmm: false,
};
},
methods: {
i1_get() {
if (!this.email) {
this.placeholder1 = "";
}
},
i2_get() {
if (!this.password) {
this.placeholder2 = "";
}
},
i1_lose() {
if (!this.email) {
this.placeholder1 = "郵箱";
}
},
i2_lose() {
if (!this.password) {
this.placeholder2 = "密碼";
}
},
input1(e) {
if (e.target.value == "") {
// console.log(val);
this.password = "";
this.placeholder2 = "密碼";
}
},
login() {
var eamil_gz =
/^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/;
switch (true) {
case this.email == "":
this.waring("郵箱不能為空!");
break;
case !eamil_gz.test(this.email):
this.error("郵箱格式錯誤");
break;
case this.password == "":
this.waring("密碼不能為空!");
break;
default:
let data = {
log_email: this.email,
log_password: this.password,
};
this.$axios
.post("/login/login", data)
// 在后臺查詢信息 返回res結(jié)果
.then((res) => {
// console.log(res.data);
switch (true) {
case res.data.code == 200:
//登錄成功
this.success(res.data.msg);
//本地存儲
localStorage.setItem("email", this.email);
localStorage.setItem("token", res.data.token);
if (this.zddl == true) {
localStorage.setItem("zddl", true);
} else {
localStorage.removeItem("zddl");
localStorage.removeItem("email");
}
if (this.jzmm == true) {
localStorage.setItem("zddl", true);
localStorage.setItem("jzmm", true);
localStorage.setItem("mm", this.password);
} else {
localStorage.removeItem("jzmm");
localStorage.removeItem("mm");
}
this.$router.push("/chat_index");
//登錄成功跳轉(zhuǎn)會有點(diǎn)閃屏,先隱藏,到另外一個(gè)路由再顯示
remote.getCurrentWindow().hide();
//登錄之后設(shè)置窗口在電腦桌面顯示位置
remote.getCurrentWindow().setPosition(386, 192);
break;
case res.data.code == 404:
//郵箱不存在
this.error(res.data.msg);
break;
case res.data.code == 300:
//密碼錯誤
this.error(res.data.msg);
break;
case res.data.code == 400:
//用戶異常
this.error(res.data.msg);
break;
default:
//未知錯誤
this.error(res.data.msg);
break;
}
})
.catch((error) => {
//報(bào)錯
});
break;
}
},
//記住密碼
jzmm_mm() {
if (this.zddl == false) {
this.zddl = true;
}
this.jzmm = true;
},
// 警告提示
waring(title) {
this.$resetMessage({
message: `${title}`,
type: "warning",
});
},
// 成功提示
success(title) {
this.$resetMessage({
message: `${title}`,
type: "success",
});
},
// 錯誤提示
error(title) {
this.$resetMessage.error(`${title}`);
},
},
mounted() {
// 讀取本地存儲賬號信息
if (localStorage.getItem("zddl")) {
this.zddl = true;
this.email = localStorage.getItem("email");
}
if (localStorage.getItem("jzmm")) {
this.jzmm = true;
this.password = localStorage.getItem("mm");
}
if (localStorage.getItem("email")) {
this.email = localStorage.getItem("email");
}
if (!this.email) {
document.getElementById("text").focus();
} else {
document.getElementById("text2").focus();
}
},
};
</script>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跟很多第三方模塊不同的一點(diǎn)是它不能直接使用use方法,而是用這種方法
//配合文章第4步解釋 本地網(wǎng)站
axios.defaults.baseURL = 'http://www.electron.com/index.php/api';//開發(fā)環(huán)境
//引入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:端口號 (生產(chǎn)環(huán)境)
connection: SocketIO('http://127.0.0.1:3000', {//開發(fā)環(huán)境
autoConnect: false // 取消自動連接
}),
extraHeaders: { 'Access-Control-Allow-Origin': '*' }
})
)
//客戶端禁止按鼠標(biāo)返回鍵返回上一個(gè)路由
window.addEventListener('popstate', function() {
history.pushState(null, null, document.URL)
})
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')7、效果圖
本地測試
npm run electron:serve

到此這篇關(guān)于electron vue 模仿qq登錄界面的文章就介紹到這了,更多相關(guān)electron vue qq登錄界面內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 關(guān)于electron-vue打包后運(yùn)行白屏的解決方案
- 用electron 打包發(fā)布集成vue2.0項(xiàng)目的操作過程
- vue與electron實(shí)現(xiàn)進(jìn)程間的通信詳情
- vue+electron實(shí)現(xiàn)創(chuàng)建多窗口及窗口間的通信(實(shí)施方案)
- vue?electron實(shí)現(xiàn)無邊框窗口示例詳解
- vue項(xiàng)目打包成桌面快捷方式(electron)的方法
- vue?+?electron應(yīng)用文件讀寫操作
- 用electron打包vue項(xiàng)目中的報(bào)錯問題及解決
- Vue?electron零基礎(chǔ)使用教程
相關(guān)文章
Vue iview-admin框架二級菜單改為三級菜單的方法
這篇文章主要介紹了Vue iview-admin框架二級菜單改為三級菜單的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-07-07
Vue路由重復(fù)點(diǎn)擊報(bào)錯問題及解決
這篇文章主要介紹了Vue路由重復(fù)點(diǎn)擊報(bào)錯問題及解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-04-04
vue中axios給后端傳遞參數(shù)出現(xiàn)等于號和雙引號的問題及解決方法
這篇文章主要介紹了vue中axios給后端傳遞參數(shù)出現(xiàn)等于號和雙引號要怎么解決,項(xiàng)目場景我是傳遞一個(gè)string字符給后端時(shí)候報(bào)錯,隨手把這個(gè)問題記錄下來了,需要的朋友可以參考下解決方案2022-11-11
Vue實(shí)現(xiàn)路由跳轉(zhuǎn)至外界頁面
這篇文章主要介紹了Vue實(shí)現(xiàn)路由跳轉(zhuǎn)至外界頁面方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-12-12
使用VUE和webrtc-streamer實(shí)現(xiàn)實(shí)時(shí)視頻播放(監(jiān)控設(shè)備-rtsp)
WebRTC-streamer是一項(xiàng)使用簡單機(jī)制通過WebRTC流式傳輸視頻捕獲設(shè)備和RTSP源的實(shí)驗(yàn),下面這篇文章主要給大家介紹了關(guān)于如何使用VUE和webrtc-streamer實(shí)現(xiàn)實(shí)時(shí)視頻播放(監(jiān)控設(shè)備-rtsp)的相關(guān)資料,需要的朋友可以參考下2022-11-11
基于vue,vue-router, vuex及addRoutes進(jìn)行權(quán)限控制問題
這篇文章主要介紹了基于vue,vue-router, vuex及addRoutes進(jìn)行權(quán)限控制問題,需要的朋友可以參考下2018-05-05
Vue Render函數(shù)創(chuàng)建DOM節(jié)點(diǎn)代碼實(shí)例
這篇文章主要介紹了Vue Render函數(shù)創(chuàng)建DOM節(jié)點(diǎn)代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07

