番茄钟评测体验

Vue番茄钟与Electron打包问题详解:学习与工作的时间管理利器

Vue番茄钟与Electron打包问题详解:学习与工作的时间管理利器

自己觉得下载的番茄钟用起来不方便?那可以试试自己动手制作一个。接下来,我会详细介绍我是如何制作 Vue 番茄钟以及如何进行打包的整个过程。我曾下载过一款番茄钟软件,满怀希望地想用它提高工作效率。然而,使用了一段时间后,我发现它并不符合我的需求。因此,我决定亲自开发一个简易的番茄钟应用,以便完全按照自己的需求来定制。// electronBuilder可以不用配置了,这是Vue CLI Plugin Electron Builder添加的才会需要

自己觉得下载的番茄钟用起来不方便?那可以试试自己动手制作一个。接下来,我会详细介绍我是如何制作 Vue 番茄钟以及如何进行打包的整个过程。

制作契机

我曾下载过一款番茄钟软件,满怀希望地想用它提高工作效率。然而,使用了一段时间后,我发现它并不符合我的需求。我希望能够有更多个性化的设置,比如自由调整专注时长等。因此,我决定亲自开发一个简易的番茄钟应用,以便完全按照自己的需求来定制。

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添加的才会需要
        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对标多少px
        .end()  //这里就是引用插件
    }
}

前期规划

"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
},

动手前,得先规划一番。我静下心来,琢磨番茄钟得有哪些功能,比如任务设定、倒计时提醒。我用 Xmind 搞了个功能思维导图。毕竟这是初版,先做基础版,以后逐步改进。

const electron = require('electron');
// 控制应用生命周期的模块。
const {app, ipcMain} = electron;
// 创建原生浏览器窗口的模块。
const {BrowserWindow} = electron;
let mainWindow;
function createWindow() {
  // 创建浏览器窗口。
  mainWindow = new BrowserWindow({
    width: 480, 
    height: 670,
    webPreferences: {
      nodeIntegration: true, 
      contextIsolation: false
    }
  });
  // 加载应用的 index.html。
  // mainWindow.loadURL(`file://${__dirname}/dist/index.html`);
  mainWindow.loadURL(`http://localhost:9001/`);
  // 启用开发工具
  mainWindow.webContents.openDevTools();
}
// Electron 会在初始化后并准备
app.on('ready', createWindow);
// 当全部窗口关闭时退出。
app.on('window-all-closed', () => {
  // 否则绝大部分应用及其菜单栏会保持激活。
  if (process.platform !== 'darwin') {
    app.quit();
  }
});
app.on('activate', () => {
  // 绝大部分应用会重新创建一个窗口。
  if (mainWindow === null) {
    createWindow();
  }
});

环境搭建

我将任务数据创建与编辑的操作,计划利用 Node 进行存储,具体保存在项目中的 json 文件中。尽管 Vue CLI 提供了 vue add 命令来安装插件,但我决定采用最基本的方法。特别提醒,在安装 less 时,需留意其版本,若版本更新过高,项目运行时可能会出现错误。安装完毕后,运行yarn start命令,若能成功看到弹窗,即表明环境搭建成功。

路由与界面设计

taskList: [
    {
        name: '学习node',
        creatTime: '',
        duringTime: 10,
        startFlag: false,
        bgSrc: 'bg1.png',
        taskEndCount: 0, 
        taskId: 'adfa455a'
    },
]

路由配置不能随便,别用vue进行路由跳转,否则在打包时可能会遇到麻烦。界面中无任务时,左上角的实时时间每秒更新一次,番茄钟任务的倒计时也会采用这种计时方法。设计任务卡片所需的数据和属性时,即使有些现在暂时不用,也应该先列出来。起初可以用测试数据,暂时不必考虑文件存储的问题。

absTipFlag: false,   // 添加任务弹窗
isRuning: false,  // 是否有任务正在进行中
countdownTime: '',  //任务倒计时
taskbeginTime: '',  // 任务开始时间
taskendTime: '',   // 任务结束时间
taskduringTime: 0,  // 任务持续时间
curTask: null,   // 当前正在进行的任务
hasProcessTime: 0,  // 任务真正耗时

数据存储与交互

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 )

由于开发桌面应用,且番茄钟任务的数据量并不大,我计划将数据直接保存在本地文件里。为此,主进程和渲染进程需要实现数据间的交流。于是,我在指定文件夹内新建了一个子文件夹,用于存放读写操作的相关代码以及.json格式的数据文件。请注意,设置文件读取路径需使用 path.join() 函数。在调试阶段,使用相对路径尚可,但一旦打包,文件便难以找到。经过多次尝试,我们最终成功创建了任务,并将其保存至 json 文件中。同时,读取文件的操作也顺利完成。

// 通过window的消息通知告知任务结束
notification(){
    let options;
    if (this.hasProcessTime == this.curTask.duringTime * 60) {
        options = {
            body: `请休息一下吧,工作辛苦啦!`,
            icon: require('../../assets/img/icon1.png')
        }
        new Notification(`恭喜,你设置的 ${this.curTask.name} 已完成`, options);
    } else {
        options = {
            body: `任务尚未成功,期待下次重来`,
            icon: require('../../assets/img/icon2.png')
        }
        new Notification(`抱歉,您提前结束了工作`, options);
    }
}

项目打包与测试

进入打包步骤。用yarn build命令对Vue项目进行打包,会创建一个名为dist的文件夹。将文件夹中的index.html文件拖入浏览器,虽然能看到效果,但会出现错误提示,这是因为浏览器存在安全防护。执行yarn命令后,会根据之前配置的.json文件中的build设置,生成一个新的文件夹。我设立了时长为一分钟的测试任务,尽管任务执行次数的记录不够完善,但这并未影响任务的核心功能。即便关闭并再次启动,任务依然能够正常运行。现在,番茄钟的0.1.0版本已经制作完成,并且可以成功安装在电脑上。

在类似项目的制作过程中,大家是否遇到过特别麻烦的问题?若觉得本文对您有帮助,请记得点赞及转发。

const path = require('path')
const { readFile, writeFile } = require('./src/assets/fs/readFs')
// 监听渲染进程发来的消息
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)
  }
})
// 保存数据
ipcMain.on('save-msg', async (event, arg) => {
  let con = await writeFile(path.join(__dirname, './public/static/tomato.json'), JSON.stringify(arg));
  console.log(con)
})

更多内容