使用 Angular 和 Electron 创建跨平台桌面应用

发布:2024-09-17 14:43 阅读:51 点赞:0

一. 简介

本文将介绍如何通过 Electron 框架将现有的 Angular 应用转换为桌面应用。Electron 允许使用 JavaScript、HTML 和 CSS 构建跨平台的桌面应用,它基于 Node.js 和 Chromium,支持 macOS、Windows 和 Linux 平台。我们将通过一个计算器应用为例,逐步展示如何将 Angular 应用转为桌面应用。

二. 创建 Angular 应用

1. 使用 Angular CLI 创建新应用

首先,使用 Angular CLI 创建一个新的 Angular 应用,命令如下:

ng new desktop-calculator

该命令将在项目目录下创建一个名为 desktop-calculator 的新 Angular 应用。

2. 编写应用代码

接下来,我们将创建一个简单的计算器应用。代码的 HTML 和 TypeScript 部分如下。

app.component.html

<div class="container">
  
  <div class="jumbotron col-sm-4 p-2 m-0 bg-inverse mx-auto" style="border: 1px solid lightgray;border-radius: 2%;">
    
    <h1 class="text-center">Angular Calculatorh1>

    
    <label style="font-weight: bolder;">Inputlabel>
    <div class="input-group input-group-sm col-sm-12 m-0 p-0">
      <div class="col-sm-12 form-control text-lg-right" type="text">{{input}}div>
    div>

    
    <label style="font-weight: bolder;">Resultlabel>
    <div class="input-group input-group-sm col-sm-12 m-0 p-0">
      <div class="form-control text-sm-right" type="text">{{result}}div>
    div>

    
    <div class="col-sm-12 p-1 m-0">
      <button class="btn btn-info col-sm-6" type="button" (click)="allClear()">Cbutton>
      <button class="btn btn-warning col-sm-3" type="button" (click)="clear()">xbutton>
      <button class="btn btn-secondary col-sm-3" type="button" (click)="pressOperator('/')">/button>
    div>

    
    <div class="col-sm-12 p-1 m-0">
      <button class="btn btn-outline-secondary col-sm-3 p-1" type="button" (click)="clickNum('7')">7button>
      <button class="btn btn-outline-secondary col-sm-3 p-1" type="button" (click)="clickNum('8')">8button>
      <button class="btn btn-outline-secondary col-sm-3 p-1" type="button" (click)="clickNum('9')">9button>
      <button class="btn btn-secondary col-sm-3 p-1" type="button" (click)="pressOperator('*')">Xbutton>
    div>

    
    <div class="col-sm-12 p-1 m-0">
      <button class="btn btn-outline-secondary col-sm-3 p-1" type="button" (click)="clickNum('4')">4button>
      <button class="btn btn-outline-secondary col-sm-3 p-1" type="button" (click)="clickNum('5')">5button>
      <button class="btn btn-outline-secondary col-sm-3 p-1" type="button" (click)="clickNum('6')">6button>
      <button class="btn btn-secondary col-sm-3 p-1" type="button" (click)="pressOperator('-')">-button>
    div>

    
    <div class="col-sm-12 p-1 m-0">
      <button class="btn btn-outline-secondary col-sm-3 p-1" type="button" (click)="clickNum('1')">1button>
      <button class="btn btn-outline-secondary col-sm-3 p-1" type="button" (click)="clickNum('2')">2button>
      <button class="btn btn-outline-secondary col-sm-3 p-1" type="button" (click)="clickNum('3')">3button>
      <button class="btn btn-secondary col-sm-3 p-1" type="button" (click)="pressOperator('+')">+button>
    div>

    
    <div class="col-sm-12 p-1 m-0">
      <button class="btn btn-outline-secondary col-sm-3 p-1" type="button" (click)="clickNum('.')">.button>
      <button class="btn btn-outline-secondary col-sm-3 p-1" type="button" (click)="clickNum('0')">0button>
      <button class="btn btn-success col-sm-6 p-1" type="button" (click)="getAnswer()">=button>
    div>
  div>
div>

代码说明:

  • app.component.html 文件负责构建计算器的用户界面,包含输入框、显示结果的区域和按钮。
  • 每个按钮点击时调用相关的 Angular 方法,处理数字输入、运算符输入、清空等操作。

app.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  // 用于存储用户的输入
  input: string = '';
  // 用于存储计算结果
  result: string = '';

  // 点击数字时执行,处理用户输入的数字
  clickNum(num: string) {
    // 不允许多次输入小数点
    if (num == ".") {
      if (this.input != "") {
        const lastNum = this.getLastOperand();
        if (lastNum.lastIndexOf(".") >= 0return;
      }
    }

    // 防止在输入的开头直接输入“0”
    if (num == "0") {
      if (this.input == "") {
        return;
      }
      const PrevKey = this.input[this.input.length - 1];
      if (PrevKey === '/' || PrevKey === '*' || PrevKey === '-' || PrevKey === '+') {
        return;
      }
    }

    // 更新输入内容
    this.input = this.input + num;
    // 实时计算结果
    this.calcAnswer();
  }

  // 获取最后一个操作数,用于判断是否已经输入小数点
  getLastOperand() {
    let pos: number;
    pos = this.input.toString().lastIndexOf("+");
    if (this.input.toString().lastIndexOf("-") > pos) pos = this.input.lastIndexOf("-");
    if (this.input.toString().lastIndexOf("*") > pos) pos = this.input.lastIndexOf("*");
    if (this.input.toString().lastIndexOf("/") > pos) pos = this.input.lastIndexOf("/");
    return this.input.substr(pos + 1);
  }

  // 点击运算符时执行,确保不会连续输入运算符
  pressOperator(op: string) {
    const lastKey = this.input[this.input.length - 1];
    if (lastKey === '/' || lastKey === '*' || lastKey === '-' || lastKey === '+') {
      return;
    }

    this.input = this.input + op;
    this.calcAnswer();
  }

  // 清除最后一个字符
  clear() {
    if (this.input != "") {
      this.input = this.input.substr(0this.input.length - 1);
    }
  }

  // 清除所有输入和结果
  allClear() {
    this.result = '';
    this.input = '';
  }

  // 计算结果
  calcAnswer() {
    let formula = this.input;
    let lastKey = formula[formula.length - 1];

    // 移除末尾的多余小数点
    if (lastKey === '.') {
      formula = formula.substr(0, formula.length - 1);
    }

    lastKey = formula[formula.length - 1];

    // 移除末尾的无效运算符
    if (lastKey === '/' || lastKey === '*' || lastKey === '-' || lastKey === '+' || lastKey === '.') {
      formula = formula.substr(0, formula.length - 1);
    }

    // 使用 eval 计算表达式的值
    this.result = eval(formula);
  }

  // 获取最终结果,并将结果显示在输入框中
  getAnswer() {
    this.calcAnswer();
    this.input = this.result;
    if (this.input == "0"this.input = "";
  }
}

代码说明:

  • clickNum() 方法处理数字输入,并确保不允许连续输入无效的字符。
  • pressOperator() 方法处理运算符输入,确保运算符不会连续输入。
  • clear() 和 `

allClear()` 方法分别用于删除最后一个字符和清空所有输入。

  • calcAnswer() 使用 eval() 函数计算当前输入的表达式结果,并实时显示。
  • getAnswer() 方法用于在用户点击等号后,将最终结果显示出来。

三. 使用 Electron 打包 Angular 应用

1. 安装 Electron 和依赖

在 Angular 项目根目录下,运行以下命令安装 Electron 及相关依赖:

npm install electron electron-packager --save-dev

2. 创建 Electron 主进程文件

在项目根目录下创建一个名为 main.js 的文件,用于配置 Electron 的主进程:

const { app, BrowserWindow } = require('electron');
const path = require('path');

// 创建一个新的窗口
let win;

function createWindow() {
  win = new BrowserWindow({
    width800,
    height600,
    webPreferences: {
      nodeIntegrationtrue,
      contextIsolationfalse
    }
  });

  // 加载 Angular 应用的 index.html 文件
  win.loadFile(path.join(__dirname, 'dist/desktop-calculator/index.html'));

  // 当窗口关闭时将引用清除
  win.on('closed', () => {
    win = null;
  });
}

// 当 Electron 准备好时创建窗口
app.on('ready', createWindow);

// 当所有窗口关闭时退出应用
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

// 当应用被重新激活时,重新创建窗口
app.on('activate', () => {
  if (win === null) {
    createWindow();
  }
});

代码说明:

  • 该文件配置了 Electron 的主进程,定义了窗口大小及加载的 HTML 文件。
  • app.on('ready', createWindow) 监听 Electron 应用准备就绪的事件,并调用 createWindow() 创建应用窗口。
  • 当所有窗口关闭时,app.on('window-all-closed') 退出应用,但在 macOS 上应用会保持活动状态。

3. 更新 package.json

最后,更新 package.json 文件以包含 Electron 启动命令:

{
  "main""main.js",
  "scripts": {
    "electron""electron ."
  }
}

4. 打包应用

运行以下命令来启动 Electron 应用:

npm run electron

四. 结论

通过以上步骤,我们成功将一个简单的 Angular 计算器应用打包为桌面应用。