Electron+Vue.jsで日報ファイル作成アプリを作ってみた
はじめに
こちらの記事で毎日投稿している?日報記事のベースとなるファイルを自動で作成するスクリプトを作成しました。
しかし、スクリプトの仕様として実行した日付が設定されるので、前日のものを作成したい場合などにはわざわざ日付を変えたりと使いづらくなりました。
なので、最近勉強しはじめたVue.jsを使ってGUIアプリケーションを作成していきたいと思います。
本記事のゴール
pythonのスクリプトと同等の機能を持つアプリケーションを作成する。 (同等機能なので今のところはpythonスクリプト実行したほうがはやいけど。。。)
環境
- Windows 10 64bit
- node v12.16.2
- npm 6.14.4
利用ライブラリ
- Element : 2.13.1
- デスクトップUIライブラリ
事前準備
element-uiインストール
element-uiをローカルインストールするために以下のコマンドを実行する。
>npm install element-ui
日報アプリの実装手順
これ以降は、前回作成した環境から変更した部分のみを書いています。
ソースコード全文を見たい方は、Githubをご確認ください。
ファイル構成
# 一部のみ記載
create_templete_file
├── resource
│ └── templete.md
└── src
├── assets
│ └── logo.png
├── components
│ └── WriteFile.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
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という単一コンポーネントを読み込んでいた箇所を専用のコンポーネントに変更しています。
<template> <div id="app"> <WriteFile/> </div> </template> <script> import WriteFile from './components/WriteFile.vue' export default { name: 'App', components: { WriteFile } } </script>
components/WriteFile.vue
メインとなるコンポーネントファイルになります。
<template> <el-main> <!-- ファイル名入力欄 --> <el-input placeholder="ファイル名を入力してください。" v-model="input" class="input-with-select"> <el-select v-model="select" slot="append" placeholder="Select"> <el-option label=".md" value=".md"></el-option> <el-option label=".txt" value=".txt"></el-option> </el-select> </el-input> <!-- 本文入力欄 --> <el-input type="textarea" :rows="2" :autosize="{ minRows: 10, maxRows: 50}" placeholder="Please input" v-model="textarea"> </el-input> <!-- ファイル読み込みボタン --> <el-button type="primary" @click="readTempleteFile()">ファイル読み込み</el-button> <!-- ファイル書き出しボタン --> <el-button type="success" @click="writeFile()">ファイル書き出し</el-button> </el-main> </template> <script> export default { data () { return { taskList: [], input: '', select: '.md', textarea: '' } }, methods: { // テンプレートファイル読み込み readTempleteFile(){ // 初期化 this.textarea="" // 現在日付取得 var dt = new Date(); var yyyy = dt.getFullYear(); var mm= ("00" + (dt.getMonth()+1)).slice(-2); var dd = ("00" + dt.getDate()).slice(-2); var dayOfWeek = dt.getDay() ; // 曜日(数値) var dayOfWeekStr = [ "日", "月", "火", "水", "木", "金", "土" ][dayOfWeek]; // 曜日(日本語表記) // パス設定 const path = require('path'); const basePath = process.cwd(); const templeteFilePath = path.resolve(basePath, './resource/templete.md'); // テンプレートファイル読み込み const fs = require('fs'); var readline = require("readline"); var stream = fs.createReadStream(templeteFilePath, "utf8"); var reader = readline.createInterface({ input: stream }); let isFileNameFlg =true; reader.on("line", (line) => { // ======= 変換仕様 ======= // 日付変換(yyyymmdd) if ( line.match(/yyyymmdd/)) { var replaceStr = yyyy + mm + dd; line = line.replace( "yyyymmdd", replaceStr ); } // 日付変換(yyyy年mm月dd日(Day)) if ( line.match(/yyyy年mm月dd日(Day)/)) { replaceStr = yyyy + "年"+ mm + "月" + dd + "日" + "(" + dayOfWeekStr + ")"; line = line.replace( "yyyy年mm月dd日(Day)", replaceStr ); } // 1行目の判定 if (isFileNameFlg) { this.input = line; isFileNameFlg =false; }else{ this.textarea += line this.textarea += '\n' } }); }, // ファイル書き出し writeFile () { const fs = require('fs'); fs.writeFileSync(this.input +this.select, this.textarea); this.$message({ message: 'ファイルが正常に出力されました。', type: 'success' }); }, } } </script> <style scoped> main.el-main { width: 600px; margin: 0px auto; } </style> <style> .el-select .el-input { width: 70px; } .input-with-select .el-input-group__prepend { background-color: #fff; } </style>
完成品
こちらが完成品になります。
機能
今回作った日報作成アプリの機能は以下になります。
現時点では、2つの変換仕様にそってテンプレートファイルの内容が変換されます。
- ファイル読み込みボタンをクリックすることで、resource配下のtemplete.mdファイルを読み込み画面に表示する。
- テンプレートファイルの仕様
- 1行目:ファイル名
- 2行目以降:本文
- 変換仕様
- yyyymmdd ⇒ ex) 20200426
- yyyy年mm月dd日(Day) ⇒ ex) 2020年04月26日(日)
- ファイル書き出しボタンをクリックすることで、create_templete_file配下にファイルを出力する。
デモ
まとめ
とりあえず、pythonスクリプトと同じことができるGUIアプリケーションは作成できました。
まだまだ以下のような課題はあるので、少しずつ改修していきたいと思います。
ビミョーなところ
- UIがいまいち。
- 実行ファイル形式exeにすると、上手く動作しない。(テンプレートファイルの読み込み先が固定なため)
- ソースコードがぐちゃぐちゃ。
- 変換仕様の文字列は全て変換されてしまう。
- ファイル出力場所がプロジェクトフォルダの直下に固定なところ。
改善したいこと
- テンプレートファイルの読み込み場所を動的に変更できるようにする。
- 出力ファイルの出力先を動的に変更できるようにする。
- 関数化する。(変換部分など)
- 文字列の置き換え対象のルールを作成する。
2020年04月26日(日) 日報
AtCoder Beginner Contest全問解いてみたチャレンジ
今日は、AtCoder Beginner Contest 164 - AtCoderに参加して下の3問を解いた。
- ABC164 A
- ABC164 B
- ABC164 C
累計として、145問!
今日の学び
【Python】リストの重複削除
続きを読む2020年04月24日(金) 日報
Electron+Vue.jsでTodoアプリを作ってみた
はじめに
前回、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をご確認ください。
ファイル構成
# 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一覧に戻す。
デモ
こちらが完成品になります。
まとめ
デスクトップUIライブラリのElementを使うだけで、簡単に見栄えの良いアプリを作成することができました。
デザインセンスがない私にとっては、これからUIライブラリはかかせないものになりそうです。
vueについてはまだまだわからないことだらけなので、機能拡充しながら引き続き勉強していきたいと思います。
参考にさせて頂いたサイト
続きを読むテーマ「ZENO-TEAL」のリンクをカスタマイズしてみた
はじめに
私のブログでは、ZENO-TEAL - テーマ ストアを利用しているのですが、 箇条書きリンク(liタグ内にaタグを設置)の見え方がいまいちだったので、cssをカスタマイズしました。
いまいちだった点
見た目がただの文字列になってしまっており、リンクとして飛べるような見た目になっていない。
こちらが記事のマークダウン(.md)になります。
## 参考にさせて頂いたサイト * [サンプルアプリをいじりながらVue.js+Electronを学ぼう! 環境構築編 - Qiita](https://qiita.com/suzuq/items/026c43ad6f2d9f8697f7) * [[Vue.js] Vue CLI 3 で electron-vue の環境を構築する方法](https://mseeeen.msen.jp/electron-for-vue-cli-3/) * [Electron+Vue.jsを使ったデスクトップアプリ開発を始める手順](https://www.virment.com/vue-electron/)
変更した点
- 自身のブログのトップ画面にログインした状態でアクセスする。
- 画面右上の[自身のID▼(ashitaka1963)] > [デザイン]をクリックする。
- サイドバーの[レンチアイコン] > [デザインCSS]をクリックする。
- テキストボックスに以下を追記する。
/* liタグ配下のaタグのアンダーライン */ li >a { text-decoration: underline; } /* マウスホバー時に背景色を変更 */ li > a:hover { background: #cce7ff; }
完成品
文字列にアンダーバーを付けています。 また、マウスオーバーした際には背景色を変更するようにしています。
続きを読む
Electron+Vue.jsの環境構築
はじめに
デスクトップアプリケーションを作りたいと思い、色々物色しているとWeb技術(HTML,CSS,JavaScript)で作成できるElectronなるものがあることを知りました。
そしてElectronでは、最近の流行りのJavaScriptフレームワークであるVue.jsも使えるとのこと。
これは、色々と勉強にもなるなと思ったので、これからElectron+Vue.jsを使って色んなアプリを作っていきたいと思います。
本記事のゴール
「よし、サンプルコードを修正してアプリケーションを開発していくぞ。」の前のあまり楽しくないけどめっちゃ重要で、つまると中々抜け出せない環境構築を行い、サンプルアプリケーションを実行するまでがゴールになります。
なお、本記事は10割近くをこの記事を参考にさせていただきました。
環境
- Windows 10 64bit
- node v12.16.2
- npm 6.14.4
利用ツールなど
- vue-cli
- Vue CLI Plugin Electron Builder
- vue-cliの拡張プラグイン
- vue-cliで作ったVueアプリケーションにElectronの構成を追加
- electron-builderを使用
- Vue-CLI 3,4のみ対応(2020/04/19時点)
事前準備
Node.jsインストール
Node.jsにアクセスして、自身の環境にあったLTS(推奨版)をダウンロードし、インストールする。
- 初期画面で[Next]をクリックする。
- End-User License Agreementで同意して[Next]をクリックする。
- Destination Folderでデフォルトで[Next]をクリックする。
- Custom Setupはデフォルトで[Next]をクリックする。
- Toold for Native Modulesはデフォルト(チェックなし)で[Next]をクリックする。
- [Install] > [Finish]で完了
参考: Node.js - Windows10へのインストール方法 (Version 12)
Node.jsインストール確認
コマンドラインからnode -v
とnpm -v
を入力してバージョンが表示されれば、nodeのインストールは完了になります。
>node -v v12.16.3 >npm -v 6.14.4
環境構築手順
Vue CLI インストール
コマンドプロンプトで下のコマンドを実行する
# グローバルインストール >npm install -g @vue/cli
Vue CLI インストール確認
コマンドプロンプトで下のコマンドを実行してバージョンが表示されればOKです。
>vue --version @vue/cli 4.3.1
この後、使用するVue CLI Plugin Electron BuilderがVue cliのバージョンに対応しているかどうかは気をつけること。
現在、v4は対応しているため、次に進む。
プロジェクト作成
プロジェクト名は初めてなので「hello_vue_electron」という名前で作成する。
下のコマンドを叩くと、デフォルトかマニュアルのどっちで作成するか聞かれたけど、今回は特にこだわりがないのでデフォルトを選択した。
# グローバルインストール >vue create hello_vue_electron
実行したパスに「hello_vue_electron」フォルダが作成されていればプロジェクトの作成は完了です。
electron-builderのインストール
Vue CLI Plugin Electron Builderを利用してvueアプリケーションが、Electronのデスクトップアプリとして動作するようにします。
Electronのバージョンは、6系を選択した。
>cd hello_vue_electron >vue add electron-builder # Choose Electron Version ^6.0.0
サンプルアプリの起動
ここまでの手順でサンプルアプリのひな型がインストールされ、デスクトップアプリケーションとして動作する状態になっている。
下のコマンドで起動すると、アプリケーションが立ち上がり画面が表示される。
>npm run electron:serve
なお、一度この手順でアプリケーションを作成した場合、これ以降は環境構築手順のプロジェクト作成から開始でOKです。 (Vue CLIはグローバルでインストールしているため。)
まとめ
環境構築というとつまりながらやるイメージがあったけど、cliとそのプラグインのおかげで特に詰まるところなく、一気に環境構築までできました。
あくまでここはスタートラインなのでこれから独自のアプリケーションを作成していきたいと思います。
参考にさせて頂いたサイト
- サンプルアプリをいじりながらVue.js+Electronを学ぼう! 環境構築編 - Qiita
- [Vue.js] Vue CLI 3 で electron-vue の環境を構築する方法
- Electron+Vue.jsを使ったデスクトップアプリ開発を始める手順
2020年04月19日(日) 日報
AtCoder Beginner Contest全問解いてみたチャレンジ
今日はさぼり。
今日の学び
Electronとは
GitHubが開発したオープンソースのソフトウェアフレームワークである。
ChromiumとNode.jsを使っており、HTML、CSS、JavaScriptのようなWeb技術で、macOS、Windows、Linuxに対応したデスクトップアプリケーションをつくることができる。
Node.jsとは
サーバサイドのJavaScript実行環境
ノンブロッキングI/Oを用いてC10K問題 (クライアント1万台接続問題)を解決する
npmとは
続きを読むNode Package Managerの略。
Node.jsのライブラリや、パッケージを管理するためのもの。
node.jsインストールしたらこれもインストールされる。