しがないPGの自衛記録

基本ずっと寝てる

Electron+Vue.jsでTodoアプリを作ってみた

f:id:ashitaka1963:20200422065206p:plain

はじめに

前回、Electron+Vue.jsの環境構築は完成したので、手始めにTodoアプリを作ってみました。

本記事のゴール

必要最低限の機能を備えたTodoアプリを開発するまでがゴールになります。

なお、本記事はこの記事を参考にさせていただきました。

環境

  • Windows 10 64bit
  • node v12.16.2
  • npm 6.14.4

利用ライブラリ

  • Element : 2.13.1
    • デスクトップUIライブラリ

事前準備

element-uiインストール

element-uiをローカルインストールするために以下のコマンドを実行する。

>npm install  element-ui

Todoアプリの実装手順

これ以降は、前回作成した環境から変更した部分のみを書いています。

ソースコード全文を見たい方は、Githubをご確認ください。

github.com

ファイル構成

# src以下のみ記載
./src
├── assets
│   └── logo.png
├── components
│   └── TodoList.vue
├── App.vue
├── background.js
└── main.js

main.js

インストールしたelement-uiを使用できるようにするためにmain.jsに以下を追加します。

// element-ui のimport
import ElementUI from 'element-ui'

// element-ui の言語を日本語に設定(デフォルト:中国語)
import locale from 'element-ui/lib/locale/lang/ja'

// element-ui のCSSをimport
import 'element-ui/lib/theme-chalk/index.css'

Vue.use(ElementUI, {locale})

background.js

TodoアプリにDevToolsは必要ないので、26行目の以下をコメントアウトします。

if (process.env.WEBPACK_DEV_SERVER_URL) {
  // Load the url of the dev server if in development mode
  win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
  // if (!process.env.IS_TEST) win.webContents.openDevTools() ←ここをコメントアウト
} else {
  createProtocol('app')
  // Load the index.html when not in development
  win.loadURL('app://./index.html')
}

App.vue

前回はHelloWorld.vueという単一コンポーネントを読み込んでいた箇所をTodoアプリ用のTodoListコンポーネントに変更しています。

<template>
  <div id="app">
    <!-- logo画像は不要のため、コメントアウト -->
    <!-- <img alt="Vue logo" src="./assets/logo.png"> -->

    <!-- 単一ファイルコンポーネントの読み込み先の変更 -->
    <!-- <HelloWorld msg="Welcome to Your Vue.js App"/> -->
    <TodoList/>
  </div>
</template>

<script>
<!-- import HelloWorld from './components/HelloWorld.vue' -->
import TodoList from './components/TodoList.vue'

export default {
  name: 'App',
  components: {
    <!-- HelloWorld -->
    TodoList
  }
}
</script>

components/TodoList.vue

メインとなるコンポーネントファイルになります。

<template>
  <el-main>
    <!-- ===== タスク入力 ===== -->
    <!-- 入力欄 -->
    <el-input v-model="input" placeholder="タスク名を入力" clearable>
      <!-- 追加ボタン -->
      <el-button slot="append" size="mini"  icon="el-icon-plus" @click="insertTask">追加</el-button>
    </el-input>

    <!-- ===== Todoタスク一覧 ===== -->
    <p>Todo</p>
    <el-table :data="taskList" :show-header="false" stripe>
      <!-- 完了ボタン -->
      <el-table-column align="center" width="100px">
        <template slot-scope="record">
          <el-button size="mini" type="primary" @click="moveDoneTask(record.$index)" circle plain></el-button>
        </template>
      </el-table-column>
      <!-- タスク名 -->
      <el-table-column prop="task" width="auto"></el-table-column>
      <!-- 削除ボタン -->
      <el-table-column align="center" width="100px">
        <template slot-scope="record">
          <el-button size="mini" type="danger" icon="el-icon-delete" @click="deleteTask(record.$index)">削除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <!-- ===== Doneタスク一覧 ===== -->
    <p>Done</p>
    <el-table :data="doneList" :show-header="false" stripe>
      <!-- 戻すボタン -->
      <el-table-column align="center" width="100px">
        <template slot-scope="record">
          <el-button size="mini" type="primary" icon="el-icon-check" @click="moveTodoTask(record.$index)" circle></el-button>
        </template>
      </el-table-column>
      <!-- タスク名 -->
      <el-table-column prop="done" width="auto"></el-table-column>
    </el-table>
  </el-main>
</template>

<script>
  export default {
    data () {
      return {
        taskList: [],
        doneList: [],
        input: ''
      }
    },
    methods: {
      // タスク追加
      insertTask () {
        // タスクが未入力の場合、エラーメッセージを表示
        if(this.input == ''){
          this.$message({
            message: 'タスク名が入力されていません。',
            type: 'error',
            duration: 1000
          });
          return false;
        }

        this.taskList.push({task: this.input})
        this.input = ''
      },
      // タスク移動(Todo⇒Done)
      moveDoneTask (index) {
        this.doneList.push({done: this.taskList[index].task})
        this.taskList.splice(index, 1)
      },
      // タスク移動(Done⇒Todo)
      moveTodoTask (index) {
        this.taskList.push({task: this.doneList[index].done})
        this.doneList.splice(index, 1)
      },
      // Todo削除
      deleteTask (index) {
        this.taskList.splice(index, 1)
      }
    }
  }
</script>

<style scoped>
  main.el-main {
    width: 600px;
    margin: 0px auto;
  }
</style>

完成品

機能

今回作ったTodoアプリの機能は以下になります。

  • タスクを入力して、追加ボタンを押すとTodo一覧に追加される。
    • 未入力の状態で、追加ボタンを押すと、エラーメッセージが表示される。
  • Todo一覧の左側の完了ボタンをクリックすると、Done一覧に移動する。
  • Todo一覧の右側の削除ボタンをクリックすると、選択行した行が削除される。
  • Done一覧の左側のチェックボタンをクリックすると、Todo一覧に戻す。

デモ

こちらが完成品になります。

f:id:ashitaka1963:20200422065247g:plain

まとめ

デスクトップUIライブラリのElementを使うだけで、簡単に見栄えの良いアプリを作成することができました。

デザインセンスがない私にとっては、これからUIライブラリはかかせないものになりそうです。

vueについてはまだまだわからないことだらけなので、機能拡充しながら引き続き勉強していきたいと思います。

参考にさせて頂いたサイト