electron?vue?模仿qq登錄界面功能實現(xiàn)
1、使用vuecli創(chuàng)建vue項目
我用的vue2
vue create qq_test
2、安裝electron
npm install electron -g //or npm install electron@12.0.11 //老版本
3、vue項目安裝Electron-builder打包工具
版本我選擇的是12
vue add electron-builder
4、在vue項目的src下有個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模塊
因為electron12版本開始就廢除了remote模塊,我們需要自己安裝
npm install @electron/remote --save //or cnpm install @electron/remote --save
能在客戶端實現(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; */ /*加一個邊框 調(diào)試樣式 最后要刪除或者更改**/ width: 430px; /*設(shè)置寬度 必須要和主進程中設(shè)置的一樣 不能大于主進程中設(shè)置的寬度 否則會出現(xiàn)滾動條*/ height: 329px; /*設(shè)置高度 必須要和主進程中設(shè)置的一樣 不能大于主進程中設(shè)置的高度 否則會出現(xiàn)滾動條*/ position: relative; /*設(shè)置為相對定位*/ /* border-radius: 4px; */ /*設(shè)置圓角*/ border: 1px solid #464545; /* 拖 */ -webkit-app-region: drag; /* 禁止?jié)L動條 */ overflow: hidden; } /** header的樣式 header中只會有一個關(guān)閉按鈕 處于右上角 */ .login header.header { position: absolute; /*設(shè)置絕對定位 因為背景在他下面*/ height: 30px; /*設(shè)置高度*/ /* border-radius: 20px 20px 0 0; */ /*給header的左上角 右上角設(shè)置圓角 不然會出現(xiàn)很尷尬的頁面*/ width: 428px; /* 因為設(shè)置了絕對定位 設(shè)置寬度*/ /* background: rgba(255, 255, 255, 0.2); */ /*暫時設(shè)置的 后面要刪除或者更改*/ text-align: right; } /** 背景 */ .login main .bg { height: 124px; /*設(shè)置高度*/ width: 430px; /*設(shè)置寬度 也可以不用設(shè)置 因為這個元素沒有設(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è)置 因為這個元素沒有設(shè)置絕對定位 所以默認(rèn)就是100%*/ height: 200px; /*設(shè)置高度 這里的高度是 主窗口(326) - footer(30) - 背景(124) 因為header設(shè)置了絕對定位 所以不用關(guān) */ /* background: green; */ /*暫時設(shè)置的 后面要刪除或者更改*/ } .login footer.footer { position: absolute; /* 設(shè)置絕對定位 要讓他處于窗口的最底部*/ height: 30px; /*設(shè)置高度 */ /* background: red; */ /*暫時設(shè)置的 后面要刪除或者更改*/ bottom: 0; /*讓footer處于底部*/ width: 397.99px; /* 因為設(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)會有點閃屏,先隱藏,到另外一個路由再顯示 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) => { //報錯 }); 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跟很多第三方模塊不同的一點是它不能直接使用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)返回鍵返回上一個路由 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)文章
Vue iview-admin框架二級菜單改為三級菜單的方法
這篇文章主要介紹了Vue iview-admin框架二級菜單改為三級菜單的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-07-07vue中axios給后端傳遞參數(shù)出現(xiàn)等于號和雙引號的問題及解決方法
這篇文章主要介紹了vue中axios給后端傳遞參數(shù)出現(xiàn)等于號和雙引號要怎么解決,項目場景我是傳遞一個string字符給后端時候報錯,隨手把這個問題記錄下來了,需要的朋友可以參考下解決方案2022-11-11使用VUE和webrtc-streamer實現(xiàn)實時視頻播放(監(jiān)控設(shè)備-rtsp)
WebRTC-streamer是一項使用簡單機制通過WebRTC流式傳輸視頻捕獲設(shè)備和RTSP源的實驗,下面這篇文章主要給大家介紹了關(guān)于如何使用VUE和webrtc-streamer實現(xiàn)實時視頻播放(監(jiān)控設(shè)備-rtsp)的相關(guān)資料,需要的朋友可以參考下2022-11-11基于vue,vue-router, vuex及addRoutes進行權(quán)限控制問題
這篇文章主要介紹了基于vue,vue-router, vuex及addRoutes進行權(quán)限控制問題,需要的朋友可以參考下2018-05-05Vue Render函數(shù)創(chuàng)建DOM節(jié)點代碼實例
這篇文章主要介紹了Vue Render函數(shù)創(chuàng)建DOM節(jié)點代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-07-07