electron-vChat聊天是一個基於electron+electron-vue+vue+vuex+Nodejs+vue-router等技術開發的高仿微信pc客戶端界面聊天室項目,實現消息發送/表情,圖片/視頻預覽,拖拽上傳/粘貼截圖發送/微信dll截圖,右鍵菜單、朋友圈/紅包/換膚等功能。css
如上圖:能夠自由切換桌面端聊天背景皮膚html
Electron 是由Github開發,用HTML,CSS和JavaScript來構建跨平臺桌面應用程序的一個開源庫。
https://electronjs.org/
至於如何搭建開發環境及使用electron-vue,可自行去查閱官網及搜資料
基於vue語法來構造 electron 應用程序的樣板代碼。
https://electron.org.cn/vue/i...
https://simulatedgreg.gitbook...vue
經過electron裏的BrowserWindow對象建立和控制瀏覽器窗口
src目錄下有main、renderer兩個文件夾,分別是主進程及渲染進程,配置窗口修改src/main/index.js文件便可。ios
let mainWin let tray let forceQuit = false let logined = false /** * 建立主窗口============================= */ function createMainWin() { mainWin = new BrowserWindow({ // 背景顏色 // backgroundColor: '#ebebeb', width: Common.WIN_SIZE_MAIN.width, height: Common.WIN_SIZE_MAIN.height, title: Common.WIN_TITLE, useContentSize: true, autoHideMenuBar: true, // 無邊框窗口 frame: false, resizable: true, // 窗口建立的時候是否顯示. 默認值爲true show: false, webPreferences: { // devTools: false, webSecurity: false } }) mainWin.setMenu(null) mainWin.loadURL(Common.WIN_LOAD_URL()) mainWin.once('ready-to-show', () => { mainWin.show() mainWin.focus() }) // 點擊關閉最小到托盤判斷 mainWin.on('close', (e) => { if(logined && !forceQuit) { e.preventDefault() mainWin.hide() }else { mainWin = null app.quit() } }) ... apptray.createTray() } app.on('ready', createMainWin) app.on('activate', () => { if(mainWin === null) { createMainWin() } }) ...
electron建立托盤圖標、托盤圖標閃爍、最小化到托盤、托盤右鍵git
/** * 托盤圖標事件 */ let flashTrayTimer = null let trayIco1 = `${__static}/icon.ico` let trayIco2 = `${__static}/empty.ico` let apptray = { // 建立托盤圖標 createTray() { tray = new Tray(trayIco1) const menu = Menu.buildFromTemplate([ { label: '打開主界面', icon: `${__static}/tray-ico1.png`, click: () => { if(mainWin.isMinimized()) mainWin.restore() mainWin.show() mainWin.focus() this.flashTray(false) } }, { label: '關於', }, { label: '退出', click: () => { if(process.platform !== 'darwin') { mainWin.show() // 清空登陸信息 mainWin.webContents.send('clearLoggedInfo') forceQuit = true mainWin = null app.quit() } } }, ]) tray.setContextMenu(menu) tray.setToolTip('electron-vchat v1.0.0') // 托盤點擊事件 tray.on('click', () => { if(mainWin.isMinimized()) mainWin.restore() mainWin.show() mainWin.focus() this.flashTray(false) }) }, // 托盤圖標閃爍 flashTray(flash) { let hasIco = false if(flash) { if(flashTrayTimer) return flashTrayTimer = setInterval(() => { tray.setImage(hasIco ? trayIco1 : trayIco2) hasIco = !hasIco }, 500) }else { if(flashTrayTimer) { clearInterval(flashTrayTimer) flashTrayTimer = null } tray.setImage(trayIco1) } }, // 銷燬托盤圖標 destroyTray() { this.flashTray(false) tray.destroy() tray = null } }
點擊窗口關閉,監聽close事件,判斷是否最小化到托盤web
// 點擊關閉最小到托盤判斷 mainWin.on('close', (e) => { if(logined && !forceQuit) { e.preventDefault() mainWin.hide() }else { mainWin = null app.quit() } })
/** * @Desc 主入口頁面JS * @about Q:282310962 wx:xy190310 */ import Vue from 'vue' import axios from 'axios' import App from './App' import router from './router' import store from './store' // 引入組件配置 import $components from './components' Vue.use($components) if (!process.env.IS_WEB) Vue.use(require('vue-electron')) Vue.http = Vue.prototype.$http = axios /* eslint-disable no-new */ new Vue({ components: { App }, router, store, template: '<App/>' }).$mount('#app')
主窗口頁面分爲側邊欄+主佈局,主佈局頂部裏含有最大/小化、關閉按鈕vue-router
<template> <div id="app"> <div class="elv-container" :style="$store.state.winSkin && {'background-image': 'url('+$store.state.winSkin+')'}"> <div class="elv-wrapper flexbox"> <!-- //側邊欄 --> <side-bar v-if="!$route.meta.hideSideBar" /> <!-- //主佈局 --> <div class="elv-mainbx flex1 flexbox flex-col"> <!-- ...頂部按鈕 --> <win-bar /> <keep-alive> <router-view></router-view> </keep-alive> </div> </div> </div> </div> </template>
配置frame: false就能實現無邊框窗體,拖動窗口功能需另行處理vuex
設置css -webkit-app-region: drag;
就能實現拖動窗口
設置-webkit-app-region: drag後,下面的元素不能點擊操做,可經過設置需點擊元素no-drag便可。axios
頂部winbar.vue組件segmentfault
import { app, remote, ipcRenderer } from 'electron' import { mapState, mapMutations } from 'vuex' let currentWin = remote.getCurrentWindow() export default { props: { title: String, }, data () { return {// 是否置頂 isAlwaysOnTop: false, // 窗口是否能夠最小化 isMinimizable: true, // 窗口是否能夠最大化 isMaximizable: true, } }, computed: { ...mapState(['isWinMaxed']) }, mounted() {if(!currentWin.isMinimizable()) { this.isMinimizable = false } if(!currentWin.isMaximizable()) { this.isMaximizable = false } if(this.isWinMaxed && currentWin.isMaximizable()) { currentWin.maximize() } // 監聽是否最大化 currentWin.on('maximize', () => { this.SET_WINMAXIMIZE(true) }) currentWin.on('unmaximize', () => { this.SET_WINMAXIMIZE(false) }) }, methods: { ...mapMutations(['SET_WINMAXIMIZE']), // 置頂窗口 handleFixTop() { this.isAlwaysOnTop = !this.isAlwaysOnTop currentWin.setAlwaysOnTop(this.isAlwaysOnTop) }, // 最小化 handleMin() { currentWin.minimize() }, // 最大化 handleMax() { if(!currentWin.isMaximizable()) return if(currentWin.isMaximized()) { currentWin.unmaximize() this.SET_WINMAXIMIZE(false) }else { currentWin.maximize() this.SET_WINMAXIMIZE(true) } }, // 關閉 handleQuit() { currentWin.close() } } }
vue如何實現編輯框contenteditable光標處插入動態表情,這裏很少介紹,能夠去看以前的一篇分享文章。
electron+vue實現div contenteditable功能|截圖
好了,基於electron+vue開發仿微信桌面聊天實例就分享到這裏,但願能有點點幫助!!💪💪
最後分享個uniapp+vue實例項目
uniapp即時聊天|vue+uniapp仿微信app聊天實例|uniapp仿微信界面