---
# System prepended metadata

title: 用 Vue3 + TypeScript + Electron 從零開始製作桌面應用程式
tags: [vue3, typescript, electron]

---

# 用 Vue3 + TypeScript + Electron 從零開始製作桌面應用程式

## 前言

在使用 Electron 寫桌面程式的時候，不管是要變更頁面上的內容，還是要取得輸入框裡的文字，JavaScript 通常都要直接和又臭又長的 HTML 打架，也會導致後期難以維護。

用像是 Vue 或 React 這類的前端框架撰寫頁面，我們就可以利用自寫元件，已拼拼圖的方式把頁面建立起來，在後期維護也會比較輕鬆。

這篇文章選擇使用 Vue 的原因是，相較於 React ，Vue 的學習門檻比較低，寫起來比較直觀好理解。

## 程式結構

### ![electron](https://hackmd.io/_uploads/Hy0EMIhX0.png) Electron 

引用自 Electron 官網上的敘述

> Electron is a framework for building desktop applications using JavaScript, HTML, and CSS. By embedding [**Chromium**](https://www.chromium.org) and [**Node.js**](https://nodejs.org) into its binary, Electron allows you to maintain one JavaScript codebase and create cross-platform apps that work on Windows, macOS, and Linux — no native development experience required.

> Electron 是一個用於建立桌面應用程式的框架，它使用 JavaScript、HTML 和 CSS。通過將 Chromium 和 Node.js 嵌入到其執行檔中，Electron 讓您維護一個 JavaScript 代碼，不需要任何原生開發經驗也能製作可以在 Windows、macOS 和 Linux 上執行的跨平台應用程式。

簡單來說就是，使用 Electron 的話就可以用寫網頁的技術來製作桌面應用程式。提供給我們的程式一個網頁瀏覽器，讓我們能在上面放網頁。

官網：https://www.electronjs.org

### ![typescript](https://hackmd.io/_uploads/BJLCxI2m0.png) TypeScript

讓 JavaScript 有類別的語言，使用 TypeScript 可以讓我們在開發時就發現一些程式碼潛在的問題，即時修復它們，避免讓這些錯誤出現在正式發行版中。

Vue 和 Electron 都有支援可以使用 TypeScript ，因此這篇文章內的程式碼都會使用 TypeScript 。

官網：https://www.typescriptlang.org

### ![vue](https://hackmd.io/_uploads/SyZ1zU3QR.png) Vue

Vue 是一個漸進式的 JavaScript 框架，它可以用非常直觀的方式寫網頁，同時也讓產生出來的網頁能保持著高效能。元件化的網頁結構也讓後期開發變得更加輕鬆好管理。

這篇文章使用的是目前最新版本的 [Vue3](https://zh-hk.vuejs.org) 。

官網：https://vuejs.org

### ![vitejs](https://hackmd.io/_uploads/BkTyGLh70.png) Vite

類似 Webpack 的東西，在這裡是用來將 .vue 和 .ts 的檔案打包起來的工具。 Vite 在法文裡有快速的意思，讓我們能專注在程式開發，剩下的事情都交給它處理就行。

官網：https://vitejs.dev

## 創建程式

### 使用 electron-forge 建立程式模板

一步一步從零開始的話會很容易出錯，因此我們這邊用已經設定好的模板來開始撰寫，可以省下很多建立環境的問題。

Electron 打包的工具有很多，不過在這裡我們就用 Electron 推建的 electron-forge 裡面的 `vite-typescript` 模板

首先我們先打開終端機，並在裡面輸入：

```bash!
npm init electron-app@latest my-new-app -- --template=vite-typescript
```

這段指令中間的 `my-new-app` 就是專案的名稱，在這篇文章中我們會照指南內的名稱做，不過你也可以自己為程式取個喜歡的名稱。

![image](https://hackmd.io/_uploads/Hkc3wUnXR.png)

### 安裝依賴

開始開發之前我們要先把專案使用的依賴先下載下來，這樣才能使用。我們先將終端機的路徑變更到剛剛創好的專案裡面：

```bash!
cd my-new-app
```

然後輸入以下指令來安裝所有有用到的依賴：

```bash!
npm install
```

### 啟動程式

安裝好後我們先確定所有東西都能正常運作，不然程式開不起來也沒辦法開始開發。輸入以下指令來啟動程式

```bash!
npm run start
```

成功開起來之後會出先一個視窗，這樣就是成功了。

![image](https://hackmd.io/_uploads/rJ8FKL27A.png)

### 添加 Vue 進到專案裡面

稍微翻一下 src 資料夾就可以發現到，現在的專案還沒有使用到 Vue 而使是使用 html 的的方式來製作的，因此我們要來改造一下這個專案。

首先我們先安裝 Vue3 ：

```bash!
npm install vue@3 @vitejs/plugin-vue
```

等待安裝完成後，我們先從 Vite 開始設定。

在專案的根目錄裡面找到 `vite.renderer.config.ts`，它應該會長得像這個樣子：

```ts=
import type { ConfigEnv, UserConfig } from 'vite';
import { defineConfig } from 'vite';
import { pluginExposeRenderer } from './vite.base.config';

// https://vitejs.dev/config
export default defineConfig((env) => {
  const forgeEnv = env as ConfigEnv<'renderer'>;
  const { root, mode, forgeConfigSelf } = forgeEnv;
  const name = forgeConfigSelf.name ?? '';

  return {
    root,
    mode,
    base: './',
    build: {
      outDir: `.vite/renderer/${name}`,
    },
    plugins: [pluginExposeRenderer(name)],
    resolve: {
      preserveSymlinks: true,
    },
    clearScreen: false,
  } as UserConfig;
});
```

我們先導入 `@vitejs/plugin-vue` 插件：

```diff=
  import type { ConfigEnv, UserConfig } from 'vite';
  import { defineConfig } from 'vite';
  import { pluginExposeRenderer } from './vite.base.config';
+ import vue from "@vitejs/plugin-vue";

  // https://vitejs.dev/config
  export default defineConfig((env) => {
```
然後將插件添加進下面的 plugin 陣列中：

```diff=15
    build: {
      outDir: `.vite/renderer/${name}`,
    },
-   plugins: [pluginExposeRenderer(name)],
+   plugins: [pluginExposeRenderer(name), vue()],
    resolve: {
      preserveSymlinks: true,
    },
```
這樣 Vite 的部分就設定好了。

接著我們來改前端的部分，我們先創一個新的檔案叫做 `App.vue` 在 `src` 資料夾裡面，這個檔案就會是我們 Vue 的入口點。

我們來把 `index.html` 裡面的 Hello World 搬到 `App.vue` 裡面：

:::spoiler 步驟一：**`index.html`**

把 `<body>` 裡面的 Hello World 剪下，加上一個 `<div id="#app"></div>`，整個檔案最後應該會長成這樣：

```html=
<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8" />
  <title>Hello World!</title>
</head>

<body>
  <div id="app"></div>
  <script type="module" src="/src/renderer.ts"></script>
</body>

</html>
```
:::

:::spoiler 步驟二：**`src/App.vue`**

接著把我們剛剛剪下的 Hello World 貼到 `App.vue` 裡面，並用 `<template>` 標籤把它包起來。

```html=
<template>
  <h1>💖 Hello World!</h1>
  <p>Welcome to your Electron application.</p>
</template>
```
:::

<br>

之後在 `src` 資料夾裡面找到 `renderer.ts` ，找到之後我們先把上面的註解和下面的程式碼清掉，只留下導入的部分。

它應該會長得像這樣：

```ts=
import './index.css';
```

接著我們就來導入 Vue 本人啦，在最上面加上：

```diff=
+ import { createApp } from 'vue';
+ import App from './App.vue';

  import './index.css';
```

導入後我們就可以用 `createApp` 來將 Vue 加進我們的 HTML 裡面，在檔案下面加上：

```ts=
createApp(App).mount('#app');
```

:::spoiler 完整程式碼：**`src/renderer.ts`**
```ts=
import { createApp } from 'vue';
import App from './App.vue';

import './index.css';

createApp(App).mount('#app');
```
:::

<br>

接著我們就可以重啟程式來看看效果了。

![image](https://hackmd.io/_uploads/BkJOSv37A.png)

這時候你可能會想問「啊怎麼跟剛剛開起來長的一模一樣？」

那是因為我們剛才只有把原本有的東西移到 Vue 裡面，我們打開開發人員工具後就可以看到 Vue 的身影了。

![image](https://hackmd.io/_uploads/ryWyID3X0.png)
> `data-v-app` 就是 Vue 的東西了

## 結語

在這篇文中，我們簡單地解釋了如何創建 Vue3 + TypeScript + Electron 的開發環境，剩下寫程式的部分就交給大家發揮了！