vue.js入門3
はじめに
vue.js入門の続きです。 前回まではvueの環境準備がほとんどだったので今回は実装をメインで 書いていきます。
実装
まずは実装してみて、その内容をチェックしていきます。
実装
<!DOCTYPE html> <html> <head> <title>My first Vue app</title> <script src="https://unpkg.com/vue"></script> </head> <body> <h1>Vue.js</h1> <div id="app"> {{ message }} </div> <script> new Vue({ el: '#app', data: { message: 'Hello Vue!'} }) </script> </body> </html>
表示される画面
普通のHelloページです。
実装内容チェック
まずはscriptの中身をチェックします。
new Vue
この部分はVueのオブジェクトを作成してます。 でその中身が以下です。
el: '#app', data: { message: 'Hello Vue!'}
elとdataというものを指定しています。
elについて
elは最低限必要となるプロパティになるようです。 指定するのはVueオブジェクトの対応となるものです。
appと指定しているので、これがid="app"と紐づく感じになります。
dataについて
dataの値に用意されたものを指定されたところ({{}}のところ)に設定するというイメージです。 ここでは{{message}}にHello Vue!という文字を設定するということになります。
messageの動きの確認
{{}}に設定された値はリアルタイムにチェックされ、常に状態が保持されるようです。 試してみます。
実装
試すために以下のように実装します。
<!DOCTYPE html> <html> <head> <title>My first Vue app</title> <script src="https://unpkg.com/vue"></script> </head> <body> <h1>Vue.js</h1> <div id="app"> {{ message }} </div> <hr> <button onclick="doAction();"> click </button> <script> var data = {message: 'Hello Vue!'} new Vue({ el: '#app', data: data }) function doAction() { data.message = "You Clicked"; } </script> </body> </html>
表示される画面
以下のように表示されます。
ここで、クリックボタンを押すと、以下の表示に変化します。
実装内容チェック
JavaScriptの実装でVueオブジェクトに設定しているdataを 最初に初期化して、そのdata変数を設定するようにしています。
そして、doActionメソッドを追加して、そこでdata.messageにYou Clickedというように メッセージを設定するようにしています。
この実装では{{message}}に設定した値が動的に切り替わることが確認できました。
さらに値を更新してみる
値が更新されるのをさらに確認してみます。
実装
テキストフィールドを表示して、そこに入力した内容をmessageにリアルタイムで出力するという内容です。
<!DOCTYPE html> <html> <head> <title>My first Vue app</title> <script src="https://unpkg.com/vue"></script> </head> <body> <h1>Vue.js</h1> <div id="app"> {{ message }} </div> <hr> <input type="text" onInput="doAction(event);"> <script> var data = {message: 'please type'} new Vue({ el: '#app', data: data }) function doAction(event) { console.log(event) data.message = event.target.value; } </script> </body> </html>
画面表示
初期表示は以下のようになります。
テキストフィールドに入力するとリアルタイムで表示されます。 (以下testを入力した後の画面です)
値以外を設定する
{{}}には今まで「値」を設定してきましたが、値以外もJavaScriptの「式」を記述することもできます。
実装
先程の入力した値を表示する実装のmessage部分を以下のように修正します。
{{ message.toUpperCase() }}
全部だと以下のようになります。
<!DOCTYPE html> <html> <head> <title>My first Vue app</title> <script src="https://unpkg.com/vue"></script> </head> <body> <h1>Vue.js</h1> <div id="app"> {{ message.toUpperCase() }} </div> <hr> <input type="text" onInput="doAction(event);"> <script> var data = {message: 'please type'} new Vue({ el: '#app', data: data }) function doAction(event) { data.message = event.target.value; } </script> </body> </html>
画面表示
以下のように表示されます。 (この時点でplease typeが大文字に)
入力すると以下のように大文字に変換されて出力されます。 (ここではtestと英語、小文字で入力)
まとめ
{{}}の用法
{{}}に式を書くことを確認しました。 制約としては、何行にも渡るものは設定できないようです。
また保守のことを考えると複雑な実装を埋め込んでしまうとメンテナンスが難しいということにもなりそうなので 式を書きすぎるようなことは気をつけないといけないですね。
vue.js入門2
はじめに
前回に続きvue.jsの入門を続けてみます。
参考文献
積読していた以下を使って進めます。 Vue.js&Nuxt.js超入門 | 掌田津耶乃 | 工学 | Kindleストア | Amazon
設定
書籍の記載によるとVue CLIを利用する際にVue cli-service-globalというものも必要なようなのでこれを インストールします。
https://www.npmjs.com/package/@vue/cli-service-global
Vue cli-service-globalのインストール
インストール方法は以下コマンドを実行します。
npm install -g @vue/cli-service-global
Hello APPを作る
ようやくフロントエンドを作成していきます。
vueファイルを用意
任意のディレクトリでapp.vueというファイルを作成します。 ファイルは以下のようにしました。
<template> <div id="app"> <h1>Hello!</h1> <p>This is message...</p> </div> </template>
※通常のHTMLとは異なる、のタグの中に必要なものを書くみたいなイメージですね。
実行
作成したファイルを実行します。以下で実行できます。 ※作成したvueファイルがあるディレクトリで実行します。
vue serve
上記コマンドを実行するとwebサーバが起動するという感じのようです。
以下にアクセスすると作成したHTMLが表示されるはずです。 http://localhost:8080/
ここでは以下のように表示されたのでOK。
ページのソースをみてみると以下のようになっていました。
<!DOCTYPE html> <html lang=""> <head> <meta charset="utf-8"> <title>Vue CLI App</title> <link href="/js/app.js" rel="preload" as="script"><link href="/js/chunk-vendors.js" rel="preload" as="script"></head> <body> <div id="app"></div> <script type="text/javascript" src="/js/chunk-vendors.js"></script><script type="text/javascript" src="/js/app.js"></script></body> </html>
app.vueで書いた内容以外のソースが生成されているのでこの部分がvueが行っていることのようです。
ここまでで、簡単なhelloAPPを作ることができました。 ※以下にuploadしました。 github.com
次により大きい単位のAPPを作ってみたいと思います。
プロジェクトを作る
前回も行ったのですが改めて作成していきます。
コマンド
vue create hello_app
プリセットの入力
以下の選択はプリセットというものを指定するということになるようです。
前回はVue 3を選択しましたが、今回はManuallyで進めてみます。
Please pick a preset
Manually select featuresを選択します。
Check the features needed for your project(組み込む項目の選択)
以下のような選択肢が表示されました。 ここでは以下画像のまま進めます。 ※デフォルトでBabel、Linter/Formatterが選択されていました。
Choose a version of Vue.js that you want to start the project with(Vueのversion選択)
vueのversion選択をするようです。ここでは3.xを選択します。
Pick a linter / formatter config(linter/formatter選択)
組み込むlinter/formatterを選択します。ここではそのまま「ESLint with error prevention only」を選択
Pick additional lint features:(lintの追加設定)
Lint on saveで進めます。
Where do you prefer placing config for Babel, ESLint, etc.?(BabelやESLintなどの設定はどこに置くのがいいですか?)
In dedicated config filesを選択します。
Save this as a preset for future projects?
ここまでに選択したものを保存するかどうかという感じなので、ここではNを選択します。
プロジェクト実行
以下コマンドを実行し動作確認をします。
npm run serve
以下にアクセスし表示されるかを確認します。 http://localhost:8080/
前回と結果は変わらないのですが、以下の画面がでているのでOK。
作成されたプロジェクトの中身を確認する。
書籍でも解説があるのですが、自分でも確認してみます。
ファイル一覧
以下のディレクトリ、ファイルが作成されていました。 * README.md * babel.config.js * node_modules * package-lock.json * package.json * public * src
とりあえず直近で使っていきそうなのが、publicフォルダと、srcフォルダの2つとの ことなので、他はおいおいみていければ良いかなと思います。
プロジェクトのビルド
実際にWebサーバに配置して公開するときは公開用のファイルを作成します。 その際のコマンドは以下を実行するようです。
npm run build
上記の実行に成功したら、「dist」というフォルダが作成されるようです。 実行時にコンソールに出力されるログの中に確かにdistというものが見えます。
⠸ Building for production... DONE Compiled successfully in 8714ms 21:32:34 File Size Gzipped dist/js/chunk-vendors.18d432dd.js 82.65 KiB 30.98 KiB dist/js/app.9b8908c6.js 4.52 KiB 1.61 KiB dist/css/app.fb0c6e1c.css 0.33 KiB 0.23 KiB Images and other types of assets omitted. DONE Build complete. The dist directory is ready to be deployed. INFO Check out deployment instructions at https://cli.vuejs.org/guide/deployment.html
lsしてみると実際にdistができています。
ls README.md dist package-lock.json public babel.config.js node_modules package.json src
このdistディレクトリの配下をさらにみてみると以下のようになっていました。
ls css favicon.ico img index.html js
上記が公開用のディレクトリになるので、ここに必要なものを用意すれば良いということになります。
まとめ
今回は簡単なvueファイルを作成して、その動作を確認する方法と 前回行ったプロジェクトを作成する方法をもう一度やり、作成されたファイルを見てみました。
次はようやく、基本的なコード部分に触れていこうと思います。
vue.js入門
はじめに
フロントエンドに疎くなってきたので、Vue.jsに入門してみます。
環境構築
いろいろやり方はあるようでCDNを使う方法であればだいぶ設定を省けそうですが、 ここではローカル環境にnodeを入れて設定する方法をしていきます。
前提
環境構築する環境はmac osを前提としています。
nodeを入れる
普通にnode.jsを入れる方法もありますが、ここではnode.jsのversion管理をできる、nvmを使った設定を していきます。
nvmの環境構築
公式はこちら
こちらも構築方法はいろいろあるようですがGit Installとされている方法を使っていきます。 手順としては
- 任意の場所でgit cloneする
- latest versionをcheckoutする
- shに追加する
- nvm.shの実行
- 設定確認
1. 任意の場所でgit cloneする
以下のようにcloneする。 ※ここではルートディレクトリ直下にcloneしています。
git clone https://github.com/nvm-sh/nvm.git .nvm Cloning into '.nvm'... remote: Enumerating objects: 8347, done. remote: Counting objects: 100% (93/93), done. remote: Compressing objects: 100% (59/59), done. remote: Total 8347 (delta 42), reused 74 (delta 34), pack-reused 8254 Receiving objects: 100% (8347/8347), 3.02 MiB | 4.50 MiB/s, done. Resolving deltas: 100% (5265/5265), done.
2. latest versionをcheckoutする
ルート直下にcloneした.nvmディレクトリに移動し、最新versionをcheckoutします。
cd ~/.nvm/ git checkout v0.38.0
3. 環境設定
.bashrcとかbash_profileなどに以下の設定を入れます。
export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
手元ではbash_profileに追加してみました。
4. nvm.shの実行
以下のようにnvm.shを実行します。
. ./nvm.sh
5. 設定確認
nvmコマンドが使えるか確認します。 以下でコマンドの結果が正常に帰ってくればOK。
nvm -help
nvmの使い方
installするnodeのversionによってコマンドがあるようです。
最新版
以下で最新版をdownloadするとのこと。
nvm install node
version指定
以下でversionを指定した方法ができるようです。
nvm install 6.14.4 # この指定だと6.14.4を指定するとのこと
installできるversionを調べる
以下でinstallできるversionを確認することができます。
nvm ls-remote
使いたいversionを指定する方法
nvm use
今回はversion指定で
LTSの最新を対象にしてみます。 ※この時点ではv14.17.4が最新のよう。
nvm install 14.17.4
nodeのversionを確認
以下コマンドでversionを確認してみます。
node --version v14.17.4
期待どおりのversionになっているので設定OKです。
Vueの設定をする
準備ができたのでここからVueの環境構築をします。
作業用ディレクトリ
適当なディレクトリに今回のプロジェクト用のディレクトリを作成しておきます。
mkdir hello-vue-app
Vue CLIをインストール
開発に使うようなのでインストールします。 cli.vuejs.org
この手順の前に実施したnodeをインストールするときに入っているnpmを使う方法、もしくは yarnを使う方法があるようです。
yarnのほうが以下の観点で良さそうですが、今回はnpmを使って進めます。 * 依存パッケージの管理が良さそう(npmだとバージョン違いの依存プログラムをインストールする可能性があるとのこと) * インストール速度が速い
実際にインストール
公式サイトに記載されているGetting Startedに従って行います。 以下コマンドでインストールします。
npm install -g @vue/cli
インストールできているか以下のコマンドで確認します。
vue --version @vue/cli 4.5.13
versionが確認できたのでOK。
Vueプロジェクトの作成
先程インストールしたVue CLIを使ってプロジェクトを作成します。
コマンドを簡単に。 ※以下のprojectnameのところを任意の名前にして実行するようです。
vue create projectname
ここではhello-vueという名前で作成してみます。
vue create hello-vue
上記コマンドを実行すると選択肢が表示されました。
ここではVue 3を選択します。 選択後、プロジェクトの初期化がされ、コマンドを実行した配下にディレクトリが作成されています。
ls hello-vue
ローカル起動
ディレクトリに移動し、以下コマンドを実行すると、vueが立ち上がります。
npm run serve
以下にブラウザでアクセスしてみます。 http://localhost:8080/
以下のような画面が表示されたので設定OKです。
まとめ
コードは何も書いていないですが、vueの環境設定を中心に行いました。 次回、コードを触ってみて、画面を動かしたいと思います。
KtorでDIを使うサンプル実装をした
はじめに
Ktorを使ったときにDIをどのように行うかを試してみました。
準備
KtorでDIをする際のアプローチとして、Koinを使う方法があったので 今回はこれを使います。
insert-koin.io ※KtorというよりかはKotlinでinjectする際のライブラリという感じか
実装
今回は以下のような順で処理をされるイメージの簡単なプログラムを作ってみます。
- Application.ktでrouting
- Controllerからusecaseの処理を呼ぶ
- usecaseで結果を返す(ここからさらにrepositoryを呼ぶなどしたいが、今回はここで固定の文字列を返します)
1. Application.ktでrouting
package com.example import com.example.usecase.HelloInteractor import com.example.usecase.HelloUsecase import com.example.web.HelloController import com.example.web.HelloControllerImpl import io.ktor.application.* import io.ktor.response.* import io.ktor.routing.* import org.koin.dsl.module import org.koin.ktor.ext.Koin import org.koin.ktor.ext.inject fun main(args: Array<String>): Unit = io.ktor.server.netty.EngineMain.main(args) @Suppress("unused") // Referenced in application.conf @kotlin.jvm.JvmOverloads fun Application.module(testing: Boolean = false) { // setting DI install(Koin) { // modulesを設定する。ここに追加したいものを追加する modules(helloModule) } // inject val helloController: HelloController by inject() routing { get("/test") { call.apply { respond("helloTest") } } get("/hello") { call.respondText(helloController.fetch()) } } } // DIの設定 val helloModule = module { single<HelloController> { HelloControllerImpl(get()) } single<HelloUsecase> { HelloInteractor() } }
2. Controllerからusecaseの処理を呼ぶ
package com.example.web import com.example.usecase.HelloUsecase interface HelloController { fun fetch(): String } class HelloControllerImpl( val usecase: HelloUsecase ) : HelloController { override fun fetch(): String { val result = usecase.fetch() return result } }
3. usecaseで結果を返す(ここからさらにrepositoryを呼ぶなどしたいが、今回はここで固定の文字列を返します)
package com.example.usecase interface HelloUsecase { fun fetch(): String } class HelloInteractor : HelloUsecase{ override fun fetch(): String { return "hello usecase result!" } }
まとめ
Application.ktでDIの設定をするコードになっているのでDIする対象が増えてきたときに 本記事の方法だとあまり良くないものになっています。 DIする方法を調べて、とりあえずDIしてみるということを目指して今回は実装してみました。
コードはこちらに。 github.com
Ktor入門
はじめに
普段はサーバーサイドKotlinの開発をしています。 そこではSpring Bootを使った開発をしているのですが 別のフレームワークを試してみようと思い、Ktorに入門してみます。
Ktorとは
jp.ktor.work Kotlinで実装されたフレームワークです。 Spring BootはJavaで実装されたものなのでKotlin製のものを使いたい時の選択肢に入ってくるものかなと 思います。
環境設定
公式によれば、以下の方法でセットアップができるとのこと。 * Maven * Gradle * start.ktor.io * InteliJ Plugin
ここではstart.ktor.ioを使って、雛形を作成し、inteliJ IDEAで実装をすすめる流れを想定して 書きます。
start.ktor.io
こちらにアクセスするとプロジェクトの雛形ができる類のものです。 (Springのspring initializr相当のものかな) start.ktor.io
みた感じだとServerとしての機能としてどのテンプレートを使うかとか clientツールとして何を使うかみたいなものを、選びやすくしているところが Spring initizlizrと違うところかなと。
設定はこのような感じで作成してみます。
ここでBuildボタンを押すことで必要な雛形をダウンロードできます。 これを適当な場所においてinteliJ IDEAでopenします。 これで開発準備は完了です。
※### 用語について start.ktor.ioページにでてくるFeatureとはライブラリの依存性にあたるものと思われます。 こちらに言及あり。
※この部分
まずはHello
ここでは単純なAPIを作ってみたいと思います。 こちらを参考にします。 jp.ktor.work
初期状態でsrc配下にApplication.ktができています。
コード
package com.example import io.ktor.application.* import io.ktor.response.* import io.ktor.routing.* fun main(args: Array<String>): Unit = io.ktor.server.netty.EngineMain.main(args) @Suppress("unused") // Referenced in application.conf @kotlin.jvm.JvmOverloads fun Application.module(testing: Boolean = false) { // ここを実装しました routing { get("test") { call.respondText("OK") } } }
実行
mainメソッドがあるのでApplication.ktを実行します。
結果
簡単ではありますがGETするAPIができました。
curl http://localhost:8080/test OK
まとめ
ソースはこちらに。 github.com
参考
まずは公式のクイックスタート jp.ktor.work
Kotlin coroutinesのasyncが動かない?
はじめに
KotlinでCoroutinesを使うときにAsync awaitを使って処理の待ち合わせをするケースがあります。 そのときに非同期処理が期待どおりに動かなかったことがあるので、記録として書いておきます。
状況
ソースにしたほうが早いので以下にソースを書きます。
ソース
import kotlinx.coroutines.* /** * 意図した動きをしないasyncのサンプル * すべてメインthreadで動いている */ fun main(args: Array<String>) = runBlocking { val resultADeferred = methodA() val resultBDeferred = methodB() println("${resultADeferred.await()},${resultBDeferred.await()}") } private suspend fun methodA() = coroutineScope { async { println("beforeA") delay(1000) println("afterA") "result A" } } private suspend fun methodB() = coroutineScope { async{ println("beforeB") delay(3000) println("afterB") "result B" } }
結果
以下の順番に出力されるのを期待していましたが、、、 1. beforeA 2. beforeB 3. afterA 4. afterB 5. result A,result B
実際には以下のように出力されました。
beforeA afterA beforeB afterB result A,result B
改善版
ソース
以下のように実装すると期待どおりに動作しました。
fun main() = runBlocking { val resultADeferred = async { methodA() } val resultBDeferred = async { methodB() } println("${resultADeferred.await()}, ${resultBDeferred.await()}") } private suspend fun methodA() = coroutineScope { println("beforeA") delay(1000) println("afterA") "result A" } private suspend fun methodB() = coroutineScope { println("beforeB") delay(3000) println("afterB") "result B" }
出力結果
beforeA beforeB afterA afterB result A, result B
違うところ
async awaitを宣言するところをmainメソッドの中にすることで期待どおりに動くようになりました。
まとめ
どうしても並列処理が期待どおりに動かなくて調査していたところ、このブログに記載した 部分が問題となり並列処理が動いていないことがわかりました。 今回はなぜ宣言場所で並列処理が動かないかについては言語化していないので改めて してみたいと思います。
本記事で使ったソースはこちら github.com
SpringBoot(kotlin)で手軽なバッチ処理を実装する
はじめに
SpringBootを使って手軽にバッチ処理のようなものを作ったのでメモがてら書きます。 SpringBootではSpringBatchという形で実装する手段があるかと思いますが 手軽な環境を構築したい場合を想定したものになります。
実装したもの
以下の構成で実装しました。
要素 | version |
---|---|
SpringBoot | 2.4.5 |
jvm | 11 |
※言語はKotlinを使います。
環境はmac os上でIntelliJ IDEA上で動作させています。
実装内容
主に実装手順になります。
雛形作成
Spring initializrを使って生成します。 https://start.spring.io/
GroupやArtifactなどは適当なものを設定しています。 入力は以下の感じになります。
これでGENERATEを押します。 すると雛形がダウンロードされるので任意の場所に配置します。
読み込み
ここからintelij ideaを使ってプロジェクトを作成します。 さきほどダウンロードした雛形ファイルを読み込むことでプロジェクトを作成します。
実装開始
動作イメージ
最終的には起動引数を設定するとアプリケーションが起動し処理が行われることがゴールになります。 これを目指します。
以下のコマンドを実行することで動作させることになります。
java -Dbatch.execute=test01 -jar light-0.0.1-SNAPSHOT.jar
処理の受け口を作る
良く作られるものはAPIだったり、Web画面用のControllerだったりすると思うのですがここでは 軽量なバッチをイメージしているものなので、起動方法がちょっと異なります。
ApplicationRunnerの実装
以下のようにApplicationRunnerを実装したクラスを作成します。 ここでは引数に渡された値によって処理が分かれるイメージを想定するので2つ作成します。
package com.hiswing.lightweight import org.springframework.boot.ApplicationArguments import org.springframework.boot.ApplicationRunner import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration class LightWeight01Runner : ApplicationRunner { override fun run(args: ApplicationArguments?) { println("lightweight01 start") } } @Configuration class LightWeight01Config { @Bean @ConditionalOnProperty(value = ["batch.execute"], havingValue = "test01") fun execute(): LightWeight01Runner? { return LightWeight01Runner() } }
2つめ
package com.hiswing.lightweight import org.springframework.boot.ApplicationArguments import org.springframework.boot.ApplicationRunner import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration class LightWeight02Runner : ApplicationRunner { override fun run(args: ApplicationArguments?) { println("lightweight02 start") } } @Configuration class LightWeight02Config { @Bean @ConditionalOnProperty(value = ["batch.execute"], havingValue = "test02") fun execute(): LightWeight02Runner? { return LightWeight02Runner() } }
起動確認
IntelliJ IDEAで動作確認
準備
引数で起動するクラスを制御しているのでその引数を設定する必要があります。 ここでは以下のようにしました。
起動確認
lightweight02 startが出力されているのを確認できました。
コマンドラインで起動確認
IntelliJ IDEAではなく、生成されたjarをコマンドで実行できることを確認します。
java -Dbatch.execute=test01 -jar build/libs/lightweight-0.0.1-SNAPSHOT.jar
以下、実行結果です。今度は、lightweight01 startと出力されているので、引数によって起動する処理が変わっているのが わかりました。
まとめ
比較的簡単にバッチのようなものの実装ができました。 軽量な処理をさっと書きたいときは便利だと思います!
実装したソースコードはこちらにあります。 github.com
参考サイト
今回の実装の参考としてこちらを参照しました。 qiita.com qiita.com SpringBatchはこちらのバッチ解説PDFを参照したい www.shoeisha.co.jp