聊聊vue番茄鐘與electron?打包問(wèn)題
序
平時(shí)對(duì)自己學(xué)習(xí)工作計(jì)劃安排可以使用番茄鐘去規(guī)劃。
番茄鐘:一個(gè)很簡(jiǎn)單的時(shí)間管理方法,設(shè)置一個(gè)固定時(shí)間,根據(jù)自己情況調(diào)整,這個(gè)時(shí)間是一個(gè)倒計(jì)時(shí),在這段時(shí)間內(nèi)認(rèn)真去做一件事情,然后一個(gè)番茄鐘結(jié)束后,休息大概五分鐘,重新番茄鐘。 這可以幫助我們量化自己的工作和效率,提醒我們休息和工作。
本人之前在手機(jī)上下載過(guò)番茄鐘的應(yīng)用,但是使用了一段時(shí)間后發(fā)現(xiàn)對(duì)我來(lái)說(shuō)并不能算十分合適,準(zhǔn)備制作一個(gè)簡(jiǎn)單的番茄鐘應(yīng)用。
原因:
- 作為一個(gè)程序員,平時(shí)工作日都是在使用電腦,手機(jī)放在旁邊,每次番茄鐘到了還要去點(diǎn)手機(jī)非常不方便
- 平時(shí)會(huì)戴著耳機(jī),可能番茄鐘響了都聽(tīng)不到
- 作為一個(gè)前端程序員,難道自己不能寫(xiě)一個(gè)電腦上的番茄鐘桌面應(yīng)用工具嘛?。?!
動(dòng)手
準(zhǔn)備工作
功能規(guī)劃
在制作一款番茄鐘前肯定要進(jìn)行規(guī)劃,先規(guī)劃自己的番茄鐘需要什么功能,然后使用xmind簡(jiǎn)單畫(huà)了一下自己需要的功能(版本0.1.0肯定先簡(jiǎn)單點(diǎn),下次一定優(yōu)化??)

開(kāi)發(fā)工具
使用的工具:vs code
使用vue cli搭建界面框架,然后通過(guò)electron將界面打包成桌面應(yīng)用。
創(chuàng)建和修改的任務(wù)數(shù)據(jù)在electron通過(guò)node進(jìn)行存儲(chǔ)在項(xiàng)目的json文件當(dāng)中。
開(kāi)發(fā)過(guò)程
創(chuàng)建項(xiàng)目
PS:打包坑比較多,關(guān)于我在打包那一塊趟過(guò)的坑準(zhǔn)備獨(dú)立寫(xiě)在另一份markdown里
- 使用
vue create tomato創(chuàng)建出番茄鐘項(xiàng)目

- 然后準(zhǔn)備添加需要的包:
electron部分:
安裝命令:yarn electron electron-builder -D
雖然vue cli可以使用vue add electron-builder安裝,但這次我還是用最原始方式來(lái)。
vue界面需要的:
- 一些符號(hào)可以使用
font-awesome來(lái)引入 - 現(xiàn)在我習(xí)慣使用
less來(lái)寫(xiě)css - px2rem-loader可以將px轉(zhuǎn)換成rem,雖然對(duì)本項(xiàng)目作用不大
安裝命令:yarn add less less-loader@7.3.0 font-awesome px2rem-loader
PS: 注意安裝的less-loader版本號(hào),如果版本過(guò)高,使用less運(yùn)行項(xiàng)目時(shí)會(huì)出現(xiàn)報(bào)錯(cuò)
配置項(xiàng)目
- 創(chuàng)建合適的
vue.config.js配置文件
以下是我vue.config.js文件
module.exports = {
publicPath: process.env.NODE_ENV === 'development' ? '/' : './', //'./',
outputDir: 'dist',
configureWebpack: {
resolve: {
alias: {
'assets': '@/assets',
'common': '@/common',
'components': '@/components',
'network': '@/network',
'views': '@/views',
'plugins': '@/plugins',
}
},
},
devServer: {
port: 9001
},
pluginOptions: {
// electronBuilder可以不用配置了,這是Vue CLI Plugin Electron Builder添加的才會(huì)需要
electronBuilder: {
}
},
chainWebpack: config => {
config.module
.rule('less')
.oneOf('vue')
.use('px2rem-loader')
.loader('px2rem-loader')
.before('postcss-loader') // this makes it work.
.options({ remUnit: 16, remPrecision: 2 }) // remUnit:讓1rem對(duì)標(biāo)多少px
.end() //這里就是引用插件
}
}- 現(xiàn)在測(cè)試一次vue項(xiàng)目是否正常運(yùn)行,
yarn serve命令運(yùn)行項(xiàng)目。正常即可

- 接下來(lái)對(duì)
electron運(yùn)行進(jìn)行配置,在package.json配置文件
"main": "electron_main.js",
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"newbuild": "electron-builder --win --x64",
"start": "chcp 65001 && electron ."
},
"build": {
"productName": "tomato",
"directories": {
"output": "electron_dist"
},
"asar": false
},并且創(chuàng)建一個(gè)electron_main.js文件,可以參考我之前的文章:《vue + electronの文件讀寫(xiě)》 xie.infoq.cn/article/ba9…
因?yàn)榇a太長(zhǎng),這里就不細(xì)說(shuō)了......
const electron = require('electron');
// 控制應(yīng)用生命周期的模塊。
const {app, ipcMain} = electron;
// 創(chuàng)建原生瀏覽器窗口的模塊。
const {BrowserWindow} = electron;
let mainWindow;
function createWindow() {
// 創(chuàng)建瀏覽器窗口。
mainWindow = new BrowserWindow({
width: 480,
height: 670,
webPreferences: {
nodeIntegration: true,
contextIsolation: false
}
});
// 加載應(yīng)用的 index.html。
// mainWindow.loadURL(`file://${__dirname}/dist/index.html`);
mainWindow.loadURL(`http://localhost:9001/`);
// 啟用開(kāi)發(fā)工具
mainWindow.webContents.openDevTools();
}
// Electron 會(huì)在初始化后并準(zhǔn)備
app.on('ready', createWindow);
// 當(dāng)全部窗口關(guān)閉時(shí)退出。
app.on('window-all-closed', () => {
// 否則絕大部分應(yīng)用及其菜單欄會(huì)保持激活。
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', () => {
// 絕大部分應(yīng)用會(huì)重新創(chuàng)建一個(gè)窗口。
if (mainWindow === null) {
createWindow();
}
});然后使用yarn start能成功出現(xiàn)彈窗即可。界面electron調(diào)用時(shí)先使用http://localhost:9001/ 即可。mainWindow.loadURL(http://localhost:9001/`);`
界面編寫(xiě)
- 接下來(lái)就該對(duì)頁(yè)面進(jìn)行修飾,設(shè)計(jì)一個(gè)合適自己的番茄鐘頁(yè)面??梢詤⒖紕e的應(yīng)用番茄鐘頁(yè)面。 界面樣式編寫(xiě)代碼不做過(guò)多敘述,雖然我是前端,但是如何設(shè)計(jì)才是值得記錄的。
注意:不要加vue-router來(lái)做路由導(dǎo)航,不然等一下打包是大坑
當(dāng)前沒(méi)有任務(wù)的界面: (左上角實(shí)時(shí)時(shí)間使用setInterval設(shè)置間隔一秒,后續(xù)番茄鐘任務(wù)倒計(jì)時(shí)也需要用到)

設(shè)計(jì)一份任務(wù)卡片需要的數(shù)據(jù)和屬性:(雖然有些目前沒(méi)有用到)
| 屬性 | 作用 |
|---|---|
| name | 任務(wù)名稱(chēng) |
| creatTime | 任務(wù)創(chuàng)建時(shí)間 |
| duringTime | 任務(wù)需要持續(xù)的時(shí)間 |
| startFlag | 是否開(kāi)始 |
| bgSrc | 背景圖片 |
| taskEndCount | 任務(wù)完成次數(shù),提前結(jié)束的不算 |
| taskId | 任務(wù)id |
然后先使用測(cè)試數(shù)據(jù),不做文件之間的存儲(chǔ)。
taskList: [
{
name: '學(xué)習(xí)node',
creatTime: '',
duringTime: 10,
startFlag: false,
bgSrc: 'bg1.png',
taskEndCount: 0,
taskId: 'adfa455a'
},
]
- 增加添加任務(wù)彈窗和倒計(jì)時(shí)彈窗

這里可以定義一些屬性,來(lái)判斷當(dāng)前的倒計(jì)時(shí)以及真正經(jīng)過(guò)的時(shí)間:
absTipFlag: false, // 添加任務(wù)彈窗 isRuning: false, // 是否有任務(wù)正在進(jìn)行中 countdownTime: '', //任務(wù)倒計(jì)時(shí) taskbeginTime: '', // 任務(wù)開(kāi)始時(shí)間 taskendTime: '', // 任務(wù)結(jié)束時(shí)間 taskduringTime: 0, // 任務(wù)持續(xù)時(shí)間 curTask: null, // 當(dāng)前正在進(jìn)行的任務(wù) hasProcessTime: 0, // 任務(wù)真正耗時(shí)
之前說(shuō)到的時(shí)間進(jìn)度:
setInterval(()=>{
this.currentTime();
this.curTime = `${this.date.year}年${this.date.mounth}月${this.date.date}日 ${this.date.hour}:${this.date.minute}:${this.date.second}`;
if (this.isRuning && this.taskduringTime > 0) {
this.hasProcessTime++;
this.taskduringTime--;
}
}, 1000 )- 并且在倒計(jì)時(shí)彈窗完成后,可以調(diào)用Notification來(lái)實(shí)現(xiàn)消息通知。
這里可以參考:《Notification 發(fā)送消息》 xie.infoq.cn/article/6d4…
// 通過(guò)window的消息通知告知任務(wù)結(jié)束
notification(){
let options;
if (this.hasProcessTime == this.curTask.duringTime * 60) {
options = {
body: `請(qǐng)休息一下吧,工作辛苦啦!`,
icon: require('../../assets/img/icon1.png')
}
new Notification(`恭喜,你設(shè)置的 ${this.curTask.name} 已完成`, options);
} else {
options = {
body: `任務(wù)尚未成功,期待下次重來(lái)`,
icon: require('../../assets/img/icon2.png')
}
new Notification(`抱歉,您提前結(jié)束了工作`, options);
}
}
主進(jìn)程和渲染進(jìn)程文件讀存通信
- 界面上的工作基本已經(jīng)完成了,下面就是對(duì)
electron發(fā)起進(jìn)攻了。
因?yàn)橐鲆粋€(gè)桌面應(yīng)用,并且番茄鐘的任務(wù)數(shù)據(jù)并不大,所以數(shù)據(jù)最好能夠直接存在本地的文件當(dāng)中。 現(xiàn)在就需要使用electron的主進(jìn)程和渲染進(jìn)程互相進(jìn)行數(shù)據(jù)交互。
因?yàn)樵?code>electron可以直接使用node,所以直接在public文件夾下創(chuàng)建一個(gè)static文件夾,里面存放讀寫(xiě)方法和tomato.json數(shù)據(jù)文件。
請(qǐng)參考:《vue + electronの文件讀寫(xiě)》
electron_main.js文件中添加ipcMain響應(yīng)方法:
注意,這里需要使用path.join(__dirname)來(lái)設(shè)置讀取文件的路徑,雖然調(diào)試時(shí)直接相對(duì)位置也可以,但是在打包后是找不到文件的
const path = require('path')
const { readFile, writeFile } = require('./src/assets/fs/readFs')
// 監(jiān)聽(tīng)渲染進(jìn)程發(fā)來(lái)的消息
ipcMain.on('render-msg', async (event, arg) => {
if (arg == '獲取番茄鐘') {
let con = await readFile(path.join(__dirname, './public/static/tomato.json') ).then(r=>r).catch(err=>err)
event.sender.send('tomato-list', con)
}
})
// 保存數(shù)據(jù)
ipcMain.on('save-msg', async (event, arg) => {
let con = await writeFile(path.join(__dirname, './public/static/tomato.json'), JSON.stringify(arg));
console.log(con)
})vue組件當(dāng)中使用window.ipcRenderer發(fā)送請(qǐng)求和響應(yīng)接收:
window.ipcRenderer.send('render-msg', '獲取番茄鐘')
window.ipcRenderer.on('tomato-list', (event, arg) => {
try {
// console.log(arg)
this.taskList = JSON.parse(arg);
} catch(e) {
this.taskList = [];
}
})
...
// 數(shù)據(jù)存入json中
window.ipcRenderer.send('save-msg', this.taskList);......
此時(shí),經(jīng)過(guò)一系列的操作后,終于能夠創(chuàng)建任務(wù)并保存到j(luò)son文件當(dāng)中了,而且也能成功讀取文件。
打包
- 現(xiàn)在要開(kāi)始打包工作了,因?yàn)槲沂褂玫牟皇?code>vue add electron-builder,所以不能一口氣打包,不過(guò)也沒(méi)有關(guān)系。
第一步: 使用yarn build將vue項(xiàng)目打包出來(lái),會(huì)生成一個(gè)dist文件夾。即使把里面的index.html拖到瀏覽器里,也是會(huì)有效果的,不過(guò)require會(huì)出錯(cuò),因?yàn)闉g覽器不允許。


第二步:先將electron_main.js中的mainWindow.loadURL修改回來(lái),變成: mainWindow.loadURL(file://${__dirname}/dist/index.html);。不然打包出來(lái)應(yīng)用會(huì)是一片空白
運(yùn)行yarn newbuild命令,根據(jù)之前package.json中的build配置,會(huì)生成electron_dist文件夾
如果打包出錯(cuò),可以參考:《關(guān)于 electron-builder 打包遇到的一點(diǎn)點(diǎn)問(wèn)題》

如何在electron_dist中下載或者直接打開(kāi)

創(chuàng)建一個(gè)1分鐘任務(wù)進(jìn)行測(cè)試:(這里我任務(wù)次數(shù)記錄沒(méi)做好,不過(guò)不影響主要功能,關(guān)閉后重新打開(kāi)任務(wù)也還是存在的)

到此,番茄鐘0.1.0版本已經(jīng)完成,并且能安裝到電腦上了。
到此這篇關(guān)于vue番茄鐘&electron 打包的文章就介紹到這了,更多相關(guān)vue electron 打包內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- vue項(xiàng)目打包成桌面快捷方式(electron)的方法
- 用electron打包vue項(xiàng)目中的報(bào)錯(cuò)問(wèn)題及解決
- 如何用electron把vue項(xiàng)目打包為桌面應(yīng)用exe文件
- electron打包vue項(xiàng)目的方法 步驟
- Electron + vue 打包桌面操作流程詳解
- electron-vue利用webpack打包實(shí)現(xiàn)多頁(yè)面的入口文件問(wèn)題
- 使用electron將vue-cli項(xiàng)目打包成exe的方法
- 用electron 打包發(fā)布集成vue2.0項(xiàng)目的操作過(guò)程
相關(guān)文章
Vue3使用ref和reactive管理狀態(tài)的代碼示例
ref 和 reactive 是 Composition API 中用來(lái)聲明響應(yīng)式數(shù)據(jù)的兩個(gè)核心函數(shù),在 Vue 3 中,使用 setup 語(yǔ)法糖可以更簡(jiǎn)潔地使用這些功能,本文將探討如何使用 ref 和 reactive 來(lái)管理狀態(tài),并解釋它們之間的區(qū)別,需要的朋友可以參考下2024-09-09
vuejs+element UI點(diǎn)擊編輯表格某一行時(shí)獲取內(nèi)容填入表單的示例
這篇文章主要介紹了vuejs+element UI點(diǎn)擊編輯表格某一行時(shí)獲取內(nèi)容填入表單的示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-10-10
vue+element實(shí)現(xiàn)批量刪除功能的示例
下面小編就為大家分享一篇vue+element實(shí)現(xiàn)批量刪除功能的示例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-02-02
vue實(shí)現(xiàn)圖片預(yù)覽放大以及縮小問(wèn)題
這篇文章主要介紹了vue實(shí)現(xiàn)圖片預(yù)覽放大以及縮小問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01
如何利用VUE監(jiān)聽(tīng)網(wǎng)頁(yè)關(guān)閉并執(zhí)行退出操作
這篇文章主要給大家介紹了關(guān)于如何利用VUE監(jiān)聽(tīng)網(wǎng)頁(yè)關(guān)閉并執(zhí)行退出操作的相關(guān)資料,因?yàn)轫?xiàng)目中需求,瀏覽器關(guān)閉時(shí)進(jìn)行一些操作處理,文中通過(guò)代碼示例介紹的非常詳細(xì),需要的朋友可以參考下2023-08-08
淺談vue中resetFields()使用注意事項(xiàng)
這篇文章主要介紹了淺談vue中resetFields()使用注意事項(xiàng),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-08-08
el-input寬度跟隨輸入內(nèi)容自適應(yīng)的實(shí)現(xiàn)方法
這篇文章主要給大家介紹了關(guān)于el-input寬度跟隨輸入內(nèi)容自適應(yīng)的實(shí)現(xiàn)方法,我們?cè)賹?shí)際應(yīng)用中可能需要input文本框能夠根據(jù)輸入字符的所占據(jù)的寬度自動(dòng)調(diào)節(jié)尺寸,需要的朋友可以參考下2023-08-08

