20210428のvue.jsに関する記事は13件です。

Spring boot + Gradle + Vue.js + MySql + VS Code + Docker (WSL2)で開発環境を構築する。

まえがき  クリアしたいこと ホストマシンに特定のjdkを入れたくない springはホットリロードもデバックもしたい docker-composeにフロントバックDBオールインワンしたい VS Code使いたい なぜ書いたか 全部盛りの情報があんまりなかったので 実際に開発を始められるところまで環境構築を書いてる情報があまりなかったので 備忘録として git この記事の最後の手順まで実施したものを置いておきます。 https://github.com/PokoPoko2ry/docker_vue_spring_sample/tree/master 前提 VS Codeインストール済み Dockerインストール済み(試した環境はDocker For Windows + WSL2) ディレクトリ構成 とりあえず下記の形でDockerのホスト環境(WSL)に作成 . ├── .devcontainer ├── docker │ ├── mysql │ │ ├── initdb │ │ └── my.cnf │ ├── spring │ └── vue ├── [spring-project] └── [vue-project] docker-compose.ymlを作成 docker/に作成 vueはデフォルトだとspringとportがぶつかるので、9000としました。 docker-compose.yml version: '3.6' services: mysql: container_name: mysql build: ../docker/mysql environment: MYSQL_DATABASE: mysqldb MYSQL_USER: user MYSQL_PASSWORD: password MYSQL_ROOT_PASSWORD: rootpassword ports: - 3306:3306 volumes: - ./mysql/initdb:/docker-entrypoint-initdb.d - mysql_db:/var/lib/mysql backend: container_name: backend build: ./spring depends_on: - mysql ports: - "8080:8080" tty: true volumes: - ../spring_project:/srv:cached working_dir: /srv frontend: container_name: frontend build: ./vue ports: - 9000:8080 volumes: - ../vue_project:/usr/src/app:cached stdin_open: true tty: true volumes: mysql_db: driver: local Dockerfileを作成 spring docker/spring に作成 FROM openjdk:11 VOLUME /tmp RUN mkdir /app WORKDIR /app vue docker/vue に作成 FROM node:lts WORKDIR /usr/src/app/ RUN npm install -g npm && \ npm install -g @vue/cli mysql docker/vue に作成 FROM mysql EXPOSE 3306 ADD ./my.cnf /etc/mysql/conf.d/my.cnf #docker runに実行される CMD ["mysqld"] docker/mysql に設定ファイルを作成しておきます。文字コードを設定。 my.conf [mysqld] character-set-server=utf8 [mysql] default-character-set=utf8 [client] default-character-set=utf8 springのプロジェクトを作成 spring initializrを使用させてもらう。 https://start.spring.io/ いったんこんな感じで作成 Generateしたら、吐き出されるZIPを解凍してspringのプロジェクト格納先に置いておきましょう。 dbの接続のために、 src/main/resources配下に、application.ymlを作成しておきます。 application.yml spring: datasource: url: jdbc:mysql://mysql:3306/mysqldb username: user password: password driver-class-name: com.mysql.cj.jdbc.Driver vueのプロジェクト作成 vue cliを使いたいので一度コンテナを立ち上げます。 $ docker-compose build $ docker-compose up -d Recreating mysql ... done Recreating frontend ... done Recreating backend ... done $ docker exec -it frontend /bin/bash はいれたらvue createでプロジェクトをお好みの内容で作成後、動作確認をします。 $ vue create . <省略> $ npm run serve npm run serveを実行すると localhost:8080 に行けと言われるかもしれませんが、composeファイルで9000番を指定したので ポートは9000番を指定します。 確認 (http://localhost:9000) ここまでできたら、一度 docker-compose downでコンテナを止めます。 $ exit $docker-compose down Removing backend ... done Removing mysql ... done Removing frontend ... done Removing network docker_default vscodeのセットアップ ホスト側(WSL上)で 拡張機能の Remote Development をインストール。 This Remote Development extension pack includes three extensions: ということで Remote - SSH Remote - Containers Remote - WSL が同時に入ります。 次に、Remote container用の設定ファイルを作成。 .devcontainer\に、devcontainer.json を作成するとremote containerにattachした時のvs codeの設定を読み込んでくれます(便利) devcontainer\devcontainer.json { "name": "spring-vue-mysql", "workspaceFolder": "/srv", "dockerComposeFile": "../docker/docker-compose.yml", "settings": { "terminal.integrated.shell.linux": "/bin/bash", }, "service": "backend", //attachするコンテナはspringを指定 "extensions": [ "vscjava.vscode-java-pack", // JavaExtensionPack "pivotal.vscode-boot-dev-pack", // Spring Boot Extension Pack "gabrielbb.vscode-lombok" //Lombok Annotations Support For VS Code ], } "name" → 設定に名前を付ける。任意の内容で大丈夫かと。 "workspaceFolder" → containerにattachした後、どのフォルダを開くか。ここではvolumeのバインド先のdirを設定 "dockerComposeFile" → 立ち上げるコンテナのcomposeファイルを指定。 "settings" → shellを指定。 "service" → composeを使用するので、どのコンテナにattachするのかを指定する。 "extensions" → container側にインストールしておきたいVS Code拡張機能のextansion Idを入力。 APIを作成 起動がうまくいったかどうかの確認で疎通を取りたいため、 java/com/example/spring-projectにAPIを作成。 vueからの実行確認を取りたいのでCORS対策でアノテーションをつけておきます。 controller/HelloController.java package com.example.spring_project.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @CrossOrigin(origins = {"http://localhost:9000"}) public class HelloController { @RequestMapping("/hello") public String hello() { return "hello world!"; } } Remote containerを実行する VS code左下の><のところを押す。 devcontainer.jsonの文法エラーがなくvscodeに正しく認識されていれば、 [Remote-Containers: Reopen in Container]が選択できると思うので実行。 json内で指定したdocker-compose.ymlをもとに、containerが立ち上がり、 containerにattachされた状態でvscodeが再起動します。 springを実行 VS Codeが立ち上がった後、左下の吹き出しでjavaのprojectをimportするか?的なことを聞かれると思うので Yesを押します。 その後、左側のメニューから 1 Run and Debugを実行。 実行環境を選ぶように言われるので、Javaを選択します。 しばらく待ちます・・・ ?のアイコンを押すと進捗が見れます。 終わると、デバッガがアプリを立ち上げてくれます。 動作確認 実行を確認します。 先ほど作成したAPIにアクセス! http://localhost:8080/hello debugを試してみます。 ついでにreturnの内容を変えて、ホットリロードされるかも試してみます。 下図のようにソースを変更、break poitnを指定して保存後、ブラウザをリロード。 このように止まり、ブラウザの内容も変わりました! vueコンテナからAPIを叩いてみます。 VS Codeのwindowを新しく立ち上げて、frontendコンテナに入ったのち、axiosをinstall $ docker exec -it frontend /bin/bash $ npm install --save axios vue-axios API実行の処理を書きます。 main.jsとApp.vueを下記のように変更。 APIのレスポンス内容をalertで表示するだけの簡単な機能を実装します。 main.js import Vue from 'vue' import App from './App.vue' import axios from 'axios' import VueAxios from 'vue-axios' Vue.config.productionTip = false Vue.use(VueAxios, axios) new Vue({ render: h => h(App), }).$mount('#app') App.vue <template> <div id="app"> <input @click="HelloWorld" type="button" value="HelloWorld"> </div> </template> <script> export default { name: 'App', methods: { HelloWorld() { this.axios.get('http://localhost:8080/hello') .then((response) => { alert(response.data); }) .catch((e) => { alert(e); }); } } } </script> vueをスタートし、実行を試してみます。 $ npm run serve → http://localhost:9000 できました? コンテナ立ち上げと同時にvueのサーバーが立ち上がるように、Dockerfileを編集します FROM node:lts WORKDIR /usr/src/app/ RUN npm install -g npm && \ npm install -g @vue/cli CMD [ "npm", "run", "serve" ] //追加 最後に 指摘や改善案、編集リクエストなどあればどんどん頂けると嬉しいです。 参考にさせていただいた記事 VS Code Vue spring & docker projectのimportに関してちょこちょこエラーが出る場合が見られました。原因がよくわかってないですが、今のところ全部VS CodeをReloadで治ってます。 ↩
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Spring boot + Vue.js + MySql + VS Code + Docker で開発環境を構築する

まえがき  クリアしたいこと ホストマシンに特定のjdkを入れたくない springはホットリロードもデバックもしたい docker-composeにフロントバックDBオールインワンしたい VS Code使いたい なぜ書いたか 全部盛りの情報があんまりなかったので 実際に開発を始められるところまで環境構築を書いてる情報があまりなかったので 備忘録として git この記事の最後の手順まで実施したものを置いておきます。 https://github.com/PokoPoko2ry/docker_vue_spring_sample/tree/master 前提 VS Codeインストール済み Dockerインストール済み(試した環境はDocker For Windows + WSL2) ディレクトリ構成 とりあえず下記の形でDockerのホスト環境(WSL)に作成 . ├── .devcontainer ├── docker │ ├── mysql │ │ ├── initdb │ │ └── my.cnf │ ├── spring │ └── vue ├── [spring-project] └── [vue-project] Dockerのセットアップ docker-compose.ymlを作成 docker/に作成 vueはデフォルトだとspringとportがぶつかるので、9000としました。 docker-compose.yml version: '3.6' services: mysql: container_name: mysql build: ../docker/mysql environment: MYSQL_DATABASE: mysqldb MYSQL_USER: user MYSQL_PASSWORD: password MYSQL_ROOT_PASSWORD: rootpassword ports: - 3306:3306 volumes: - ./mysql/initdb:/docker-entrypoint-initdb.d - mysql_db:/var/lib/mysql backend: container_name: backend build: ./spring depends_on: - mysql ports: - "8080:8080" tty: true volumes: - ../spring_project:/srv:cached working_dir: /srv frontend: container_name: frontend build: ./vue ports: - 9000:8080 volumes: - ../vue_project:/usr/src/app:cached stdin_open: true tty: true volumes: mysql_db: driver: local Dockerfileを作成 spring docker/spring に作成 FROM openjdk:11 VOLUME /tmp RUN mkdir /app WORKDIR /app vue docker/vue に作成 FROM node:lts WORKDIR /usr/src/app/ RUN npm install -g npm && \ npm install -g @vue/cli mysql docker/vue に作成 FROM mysql EXPOSE 3306 ADD ./my.cnf /etc/mysql/conf.d/my.cnf #docker runに実行される CMD ["mysqld"] docker/mysql に設定ファイルを作成しておきます。文字コードを設定。 my.conf [mysqld] character-set-server=utf8 [mysql] default-character-set=utf8 [client] default-character-set=utf8 環境のセットアップ springのプロジェクトを作成 spring initializrを使用させてもらう。 https://start.spring.io/ いったんこんな感じで作成 Generateしたら、吐き出されるZIPを解凍してspringのプロジェクト格納先に置いておきましょう。 dbの接続のために、 src/main/resources配下に、application.ymlを作成しておきます。 application.yml spring: datasource: url: jdbc:mysql://mysql:3306/mysqldb username: user password: password driver-class-name: com.mysql.cj.jdbc.Driver vueのプロジェクト作成 vue cliを使いたいので一度コンテナを立ち上げます。 $ docker-compose build $ docker-compose up -d Recreating mysql ... done Recreating frontend ... done Recreating backend ... done $ docker exec -it frontend /bin/bash はいれたらvue createでプロジェクトをお好みの内容で作成後、動作確認をします。 $ vue create . <省略> $ npm run serve npm run serveを実行すると localhost:8080 に行けと言われるかもしれませんが、composeファイルで9000番を指定したので ポートは9000番を指定します。 確認 (http://localhost:9000) ここまでできたら、一度 docker-compose downでコンテナを止めます。 $ exit $docker-compose down Removing backend ... done Removing mysql ... done Removing frontend ... done Removing network docker_default vscodeのセットアップ ホスト側(WSL上)で 拡張機能の Remote Development をインストール。 This Remote Development extension pack includes three extensions: ということで Remote - SSH Remote - Containers Remote - WSL が同時に入ります。 次に、Remote container用の設定ファイルを作成。 .devcontainer\に、devcontainer.json を作成するとremote containerにattachした時のvs codeの設定を読み込んでくれます(便利) devcontainer\devcontainer.json { "name": "spring-vue-mysql", "workspaceFolder": "/srv", "dockerComposeFile": "../docker/docker-compose.yml", "settings": { "terminal.integrated.shell.linux": "/bin/bash", }, "service": "backend", //attachするコンテナはspringを指定 "extensions": [ "vscjava.vscode-java-pack", // JavaExtensionPack "pivotal.vscode-boot-dev-pack", // Spring Boot Extension Pack "gabrielbb.vscode-lombok" //Lombok Annotations Support For VS Code ], } "name" → 設定に名前を付ける。任意の内容で大丈夫かと。 "workspaceFolder" → containerにattachした後、どのフォルダを開くか。ここではvolumeのバインド先のdirを設定 "dockerComposeFile" → 立ち上げるコンテナのcomposeファイルを指定。 "settings" → shellを指定。 "service" → composeを使用するので、どのコンテナにattachするのかを指定する。 "extensions" → container側にインストールしておきたいVS Code拡張機能のextansion Idを入力。 APIを作成 起動がうまくいったかどうかの確認で疎通を取りたいため、 java/com/example/spring-projectにAPIを作成。 vueからの実行確認を取りたいのでCORS対策でアノテーションをつけておきます。 controller/HelloController.java package com.example.spring_project.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @CrossOrigin(origins = {"http://localhost:9000"}) public class HelloController { @RequestMapping("/hello") public String hello() { return "hello world!"; } } 環境の立ち上げと動作確認 Remote containerを実行する VS code左下の><のところを押す。 devcontainer.jsonの文法エラーがなくvscodeに正しく認識されていれば、 [Remote-Containers: Reopen in Container]が選択できると思うので実行。 json内で指定したdocker-compose.ymlをもとに、containerが立ち上がり、 containerにattachされた状態でvscodeが再起動します。 springを実行 VS Codeが立ち上がった後、左下の吹き出しでjavaのprojectをimportするか?的なことを聞かれると思うので Yesを押します。 その後、左側のメニューから 1 Run and Debugを実行。 実行環境を選ぶように言われるので、Javaを選択します。 しばらく待ちます・・・ ?のアイコンを押すと進捗が見れます。 終わると、デバッガがアプリを立ち上げてくれます。 動作確認 実行を確認します。 先ほど作成したAPIにアクセス! http://localhost:8080/hello debugを試してみます。 ついでにreturnの内容を変えて、ホットリロードされるかも試してみます。 下図のようにソースを変更、break poitnを指定して保存後、ブラウザをリロード。 このように止まり、ブラウザの内容も変わりました! vueコンテナからAPIを叩いてみます。 VS Codeのwindowを新しく立ち上げて、frontendコンテナに入ったのち、axiosをinstall $ docker exec -it frontend /bin/bash $ npm install --save axios vue-axios API実行の処理を書きます。 main.jsとApp.vueを下記のように変更。 APIのレスポンス内容をalertで表示するだけの簡単な機能を実装します。 main.js import Vue from 'vue' import App from './App.vue' import axios from 'axios' import VueAxios from 'vue-axios' Vue.config.productionTip = false Vue.use(VueAxios, axios) new Vue({ render: h => h(App), }).$mount('#app') App.vue <template> <div id="app"> <input @click="HelloWorld" type="button" value="HelloWorld"> </div> </template> <script> export default { name: 'App', methods: { HelloWorld() { this.axios.get('http://localhost:8080/hello') .then((response) => { alert(response.data); }) .catch((e) => { alert(e); }); } } } </script> vueをスタートし、実行を試してみます。 $ npm run serve → http://localhost:9000 できました? コンテナ立ち上げと同時にvueのサーバーが立ち上がるように、Dockerfileを編集します FROM node:lts WORKDIR /usr/src/app/ RUN npm install -g npm && \ npm install -g @vue/cli CMD [ "npm", "run", "serve" ] //追加 最後に 指摘や改善案、編集リクエストなどあればどんどん頂けると嬉しいです。 参考にさせていただいた記事 VS Code Vue spring & docker projectのimportに関してちょこちょこエラーが出る場合が見られました。原因がよくわかってないですが、今のところ全部VS CodeをReloadで治ってます。 ↩
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Vue.js お勉強メモ

はじめに 仕事で使う事になったので1からVue.jsについて学んだ(元々Angularでプロダクト開発やっていた事はあったんだけどAngularはだめか・・・)。 その際にちゃんと覚えておかないとまずそうな事がいくつかあったのでそれを備忘録として残しておく。 ※絶賛お勉強中で随時更新しています。 Index computedとmethodsの違い computedとwatchの使い分け computedとmethodsの違い 見た目の挙動は同じだが、動きには大きな違いがあるのでちゃんと使い分けないといけないのがcomputedとmethods。 それぞれについてまとめると以下の表のようになる。 あるべきとしては関係のある部分が更新された時だけ変更されるべきなのでcomputedを用いるのが正解。 # 説明 実行タイミング computed 動的なプロパティを定義できるプロパティ。プロパティなので必ずreturnが必要。 依存関係(参照先の値)が更新された時だけ実行。 method メソッドを定義できるプロパティ。 DOMが再描画されたときに毎回実行。 以下の動画のようにconsole.log()を出すとその違いが良く分かる。 動画のソースコードは以下。 sample.html <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="app"> <p>{{ counter }}</p> <button @click="counter += 1">+1</button> <p>{{ anotherCounter }}</p> <button @click="anotherCounter += 1">他の+1</button> <p>{{ lessThanThreeComputed }}</p> <p>{{ lessThanThreeMethod() }}</p> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <script> new Vue({ el: '#app', data: { counter: 0, anotherCounter: 0 }, computed: { lessThanThreeComputed: function () { console.log('computed'); return this.counter > 3 ? '3より上' : '3以下'; } }, methods: { lessThanThreeMethod: function () { console.log('methods'); return this.counter > 3 ? '3より上' : '3以下'; } } }) </script> </body> </html> ※ちなみにdataプロパティは動的なものは表現できず初期値を定義するだけに使われるので以下のような事はできない data-prop.js new Vue({ el: '#app', data: { counter: 0 // lessThanThree: this.counter <-できない // lessThanThree: counter > 3 ? '3より上' : '3以下' <-できない } }) computedとwatchの使い分け どちらも依存関係(参照先の値)が更新された時に実行されるというのは同じだが、以下のように使い方の部分で違いがある。 # 使い分け computed ・同期処理を実行する場合に使用(returnなので基本的には同期処理) ※ただし頑張れば非同期的な処理もできる watch ・非同期処理を実行する場合に使用・参照先の値を持つプロパティがHTML上に定義されていない時に使用 ※ただし、何か参照先の値が変更された時に・・・の処理実行でのBest Practiceはcomputedを用いる事。どうしても対応不可能な場合にのみwatchを利用するようにするのがポイント。 参照先の値を持つプロパティがHTML上に定義されていない時に使用 の例 「(依存関係(参照先の値)が更新された時に何かを実行したいが、)参照先の値を持つプロパティがHTML上に定義されていない時に使用」とは以下のようなイメージ。 動画のソースコードは以下。 sample.html <body> <div id="app"> <p>{{ counter }}</p> <button @click="counter += 1">+1</button> <!-- 今回は参照先の値を持つプロパティがHTML上に定義されていない--> <!-- <p>{{ lessThanThree }}</p> --> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <script> new Vue({ el: '#app', data: { counter: 0 }, computed: { lessThanThree: function () { console.log('computed'); return this.counter > 3 ? '3より上' : '3以下'; } }, watch: { counter: function () { console.log('watch'); } } }) </script> </body> 同期・非同期 の例 sample.html <body> <div id="app"> <p>{{ counter }}</p> <button @click="counter += 1">+1</button> <p>{{ lessThanThree }}</p> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <script> new Vue({ el: '#app', data: { counter: 0 }, computed: { lessThanThree: function () { return this.counter > 3 ? '3より上' : '3以下'; } }, watch: { counter: function () { const vm = this; setTimeout(function () { vm.counter = 0; }, 3000) } } }) </script> </body> ※上記でconst vm = this;としている理由はこちらを参照
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

カウントボタンの書き方

Vue.jsでクリックすると数が増えていくカウントボタンの書き方をメモとして残しておこうと思います。 App.vue <template> <div id="app"> <button v-on:click="number += 1">ボタン</button> <h1>{{ number }}回</h1> </div> </template> <script> export default { data: function() { return { number: 0 , } }, }; </script> 以上です。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Nuxt.js+Netlifyで算数ドリルを生成するサイトを作ったお話。

フロント技術に強い友人の助けを借りて、色々と試しつつサーバレスWebアプリを作ってみたので、技術要素とか工夫した点を書きたいと思います。 作ったサーバレスWebアプリ 「おさらいクラブ」 子供の学習サポートで「やらせたい算数ドリル」を何度も印刷できるようにするのが目的で、コンテンツの追加にあたっては現時点では私の子供の学習状況が基準となっています。 作った経緯はこちらをご参照ください。(スキしてくれたら嬉しいです) ↓↓↓↓↓ 環境サマリ 言語とか Node.js Vue.js Vuex Nuxt.js(SSG, nuxt/content) Bulma(css framework) KaTeX(計算式のレンダリング用) ローカル環境 VSCode Discord(チームコミュニケーション) サーバ環境 Netlify(静的サイト構築、問い合わせフォーム) Github Cloudinary(画像用CDN) その他 お名前ドットコム Google Analytics Search Console Data portal(レポーティング) 開発前のディスカッション 作り始める前にMiroを使って簡単にサービスデザインを行いました。ざっくり以下のようなことを設定しています。 どういったサービスにしたいか? 誰のために何をしたいのか?(課題、ペルソナ、バリュー) 競合サービス分析と差別化のポイント 前提や制約の整理 大まかな技術構成 大まかなゴールイメージ その後、基本設計として以下を作成しながらイメージを具体化させました。 画面遷移図(利用導線の仮決め) ワイヤーフレーム デザイン方針 ↓ディスカッション時のスクリーンショットです。 プライベートでモノづくりする場合も資料で計画を言語化することで、 ゴールが解らず作ってる途中で飽きる 共同作業者との認識齟齬が出る 技術選定がマッチしているのかわからない 将来的な拡張性を踏まえて設計・実装できない 次に何をすれば良いか迷う 同じことを二人でやってしまう(分担できてない) こういった事が起こらないのが良いですね。 目標や計画を立てるのは仕事で何度も行ってきた経験が活かされました。意思疎通しながら組み立てていくのは楽しいです。 環境構築のコンセプト 費用はなるべくかけたくない vue.js関連のフロント技術の勉強も兼ねて作りたい 片手間でも拡充できるようコンテンツ追加をしやすくしたい なるべく費用と手間をかけたくない どのように作っていくか考えるにあたって、AWSやGCPでサーバを立てるか?と考えもしましたが、サービスの検討をした結果、当面はDBを持つ必要が無いという結論に至りました。 また、クラウド環境でホスティング出来れば十分な機能だったので、無料で利用出来て丁度良いプランのホスティングサービスを探しました。 今回は無料プランで以下が可能なNetlifyにしました。 設定が簡単ぽい Githubのプライベートリポジトリからデプロイできる フォームを使える ABテストとかしやすそう(まだ使ってない) ホスティングサーバでジェネレートできる 容量を気にしなくてよい カスタムドメインを設定可能 SSL対応 Vercel、Firebase hosting、Cloudflare pagesなど、大体どこを使っても似たようなことが出来ますが、設定が簡単そうだったこともあり総合的に判断して決めています。 無料で出来ちゃうのは助かるー。 ドメインはお名前ドットコムにて、安くて丁度良いものを選びました。 ということで、かかった費用は以下の通りです。 科目 費用 Netlify 0円 ドメイン 60円 その他 0円 合計 60円 とってもお安いです。 加えてGithubリポジトリへのマージを検知してデプロイしてくれるので楽ちんです。 なお、フォームに関しては、Googleフォームも考えましたが、せっかくなのでNetlifyのフォームを利用しています。 コンテンツ拡張をしやすくする(nuxt/contentの活用) 以下のコンテンツはnuxt/contentを使うことで、更新作業を楽にしています。 開発者ブログ(/content) 算数ドリルの解説ページ(/commentary) その他アップデート情報などのページ(/update など) それぞれのページ用途によってデザインを調整できるよう、pagesを分けて作成しています。 例えば、開発者ブログはタグ設定やヘッダ画像を設定できるようにすることで、一覧での表示やカテゴライズを管理できるようにしたり、解説ページは余計な情報を排除して解説内容のみのシンプルな構成にしたりという感じです。 開発者ブログの更新に関しては、contentページを新規追加していくだけなので、featureを作る必要もなく手数が減らせて良いです。 コンテンツ拡張をしやすくする(ロジックの工夫) オブジェクトの責務を考えつつ、最小工数で追加していけることと、追加時に影響が出ないような構造にしました。 これが良い感じにハマッて追加作業の工数は極めて小さくなっています。 また、作り始めの状態から既に何度かのリファクタリングをかけましたが、規模が小さい状態からリファクタリングを行ったことで、技術負債を溜め込まないようにしています。これも結果的に工数の削減に大きく貢献しています。 Qtta的にはここの内容をより具体的に書いた方が良いのかなと思いますが、ここを書き出すとキリが無いので割愛します。 月次レポーティングの自動化 敢えて書くほど大層なことはしていませんが、、、 GAとSearch ConsoleはData Portalでレポーティングして、月次レポートが配信されるように設定しました。 が、GAの仕様が変わってて思ったようにレポート取れてないので、この辺はこれから調整していかないといけないですね。 今のところ注視するほどデータが取れていないので、追って対応していくつもりです。 数式の表現 これはかなり苦戦しました。始めは自力で数式を表現させていましたが、筆算系はCSSで表現するには複雑過ぎました。 そして、色々とネットを探し回って辿り着いたのがKaTeXです。 そもそもTex記法というのも初めて見たので最初は全く理解できませんでしたが、Tex記法にさえ慣れてしまえば非常に使いやすいライブラリです。 ネットでLaTeXの資料は見かけますが、KaTeXに関連する資料は少ないので苦労しました。 全く予定はありませんが、高校生以上の数学を扱う場合にこのライブラリが更に活かされそうです。 コンテンツで使う画像 コンテンツ内で利用する画像は、当初Githubで管理しようとしていましたが、リポジトリを軽くしておきたかったのと、変更しやすさを重視して外部のCDNを使うようにしました。 CDNサービスも当然ながら無料で使えるものをベースに、画像のアップロードのしやすさや、画像編集など付加機能を考慮しCloudinaryを利用するようにしています。 Cloudinaryのメリットは、 アップロードが簡単 CLIもある(ほとんど使ってない) APIとして画像を取得できる(使ってない) 無料で使える範囲が広い クレジットという独自単位で利用料を計算 無料だと25クレジット使える ストレージ容量やアクセス数でクレジットを消費 クレジットは過去30日分で計算されるため、毎日減ったり増えたりする 今のところクレジットは1%しか使われていない URL画像をカスタマイズできる(超便利!) 画像サイズを変えたりトリミングできる 文字を入れたりできる フィルタとか入れられる カスタマイズをセットにして名前付きで定義できる CloudinaryはブラウザでTransformationを設定できるので、非エンジニアでもカスタマイズもしやすくて良いんじゃないでしょうか。 さいごに 大体こんな感じです。 サーバレス環境の開発というのは初めてやってみましたが、思ったよりしっかりとしたものを作れて良いですね。 今後は算数ドリルのコンテンツを追加しつつ、虫食い算など問題の出し方を拡張していくのと、既存のアプリなどのようにブラウザ上やモバイルアプリで解いたり出来るようにしていく予定です。 あと広告も入れます。 「マネジメント+開発」「チームの成長」「ビジネスと開発を繋ぐ」 南原 錦善 note:https://note.com/kinzen Twitter:https://twitter.com/kinzenmirrorro1 Facebook:https://www.facebook.com/100011962923868 是非フォロー、友達登録をお願いします! 色々な話をするのが好きなので、ちょっとだけビジネスの相談をしてみたいとか、カジュアルディスカッションしてみたいとか大歓迎です!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

domをいじってclassを付加(モーダルの出現中にページスクロールをさせない、一定の高さスクロールしたらtableのheaderを固定する等)

document.getElementById('hogeID').classList.add('fix') document.getElementById('hogeID').classList.remove('fix') document.body.classList.remove('no-scroll') document.getElementsByClassName('test')[0] 例:一定の高さスクロールしたらtableのheaderを固定する /** * tableのheaderを固定処理 */ onScroll(e) { const fixTableTop = document.getElementById('fugaID').getBoundingClientRect().top if (fixTableTop < 140) { document.getElementById('tableHeader').classList.add('fix') } else { document.getElementById('tableHeader').classList.remove('fix') } }, 参考 Document.getElementsByClassName() Element.getBoundingClientRect() モーダルを開いている時にページがスクロールしてしまうのを防ぐCSSとJavaScriptのテクニック
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Vue.js基礎】コンポーネントを作成してApp.vueを編集する

やりたいこと Vue.jsコンポーネントの基礎を学習する。 .vueファイルを編集して画面表示を確認する。 前提 Vue.jsの実行環境が構築済みであること。 まだの場合は環境構築手順 AlmaLinux8.3にvue-cli@2.9.6をインストールしてVue.jsを動かすまで https://qiita.com/kenichiro-yamato/items/7f946e0215d4f08e4eca を参照。 src/App.vue 編集 Vueプロジェクトを作成すると、下記のようなファイルやディレクトリが生成される。 HTML, CSS, JavaScriptの経験者でVue.jsが初めての人は、最初に src/App.vue を編集すると動作が理解しやすい。 エディタ等で上書きできない場合はパーミッションを確認する。 chmod 777 src chmod 777 App.vue たとえばApp.vueを下記のように修正する。 App.vue <template> <div> <h1>{{ main_title }}</h1> <h2>{{ sub_title }}</h2> </div> </template> <script> export default { data(){ return { main_title: "ここにメインタイトルを記入する。あいうえお。", sub_title: "ここにサブタイトルを記入する。かきくけこ。" } } } </script> <style scoped> h1{color: red} h2{color: blue} </style> 日本語が文字化けする場合は、 .vueファイルの文字コードをutf8にする。 .vueファイルに、別の.vueファイルを読み込む App.vue と同じディレクトリに Tokyo.vue Osaka.vue を作成し、その2ファイルを App.vueで読み込んで表示する。 Tokyo.vue Tokyo.vue <template> <div> <h1>{{ main_title }}</h1> <h2>{{ sub_title }}</h2> </div> </template> <script> export default { data(){ return { main_title: "東京都", sub_title: "とうきょうと" } } } </script> <style scoped> h1{color: red} h2{color: blue} </style> Osaka.vue Osaka.vue <template> <div> <h1>{{ main_title }}</h1> <h2>{{ sub_title }}</h2> </div> </template> <script> export default { data(){ return { main_title: "大阪府", sub_title: "おおさかふ" } } } </script> <style scoped> h1{color: orange} h2{color: green} </style> App.vue App.vue <template> <div> <Tokyo></Tokyo> <Osaka></Osaka> </div> </template> <script> import Tokyo from './Tokyo.vue' import Osaka from './Osaka.vue' export default { components: { Tokyo, Osaka } } </script> ファイルは同じディレクトリに置いてある。 ブラウザでの表示は下記の通り。 componentsディレクトリ src ディレクトリの中に components というディレクトリがあらかじめ作成されており、 この中にTokyo.vueやOsaka.vueファイルを置いてApp.vueにて App.vue import Tokyo from './components/Tokyo.vue' import Osaka from './components/Osaka.vue' のように読み込むことも可能。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

vueのfiltersを使って、数値→2桁や3桁の文字列にして表示する

例えば「1」を 「01」もしくは 「001」表記にしたいとき <div> {{ item.hogeTime | value2N }}分 </div> <div> {{ item.hogeTime | value3N }}分 </div> filters: { value2N(value) { return ('0' + value).slice(-2) }, value3N(value) { return ('00' + value).slice(-3) } } 分数の表示などに。 参考: String.prototype.slice()
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Vue2 コンポーネントまとめ ②

はじめに Vue.jsを理解する上で重要なコンポーネント。 その理解を深めるためにまとめておきます。 Vu2 コンポーネントまとめ① データの受け渡し 次はコンポーネント間でのデータの受け渡しについてまとめます。 コンポーネント間でのデータの受け渡しができれば別々に作成されたコンポーネントを連携して利用することができます。 そもそもコンポーネントの親子関係とは コンポーネントのテンプレートで他のコンポーネントを使うことを、コンポーネントの親子関係と呼びます。 親コンポーネントとはこの例では、hello-worldのコンポーネントを利用したVueインスタンスです。 html <div id="app"> <hello-world></hello-world> </div> 子コンポーネントはVue.componentで作成したhello-worldになります。 javascript Vue.component('hello-world',{ template : '<h1>Hello World</h1>' }) Vueにおけるコンポーネントの親子関係は 親はコンポーネントを利用する側 子はコンポーネントを利用される側 になります。 上記の例だとのHTMLが親、Vueコンポーネントが子になるとのこと。 ややこしいですが。 親子関係はVueインスタンスとコンポーネントのパターンだけでなく コンポーネントとコンポーネントというパターンもあります。 javascript Vue.component('comp-parent', { template: '<div><h1>componentの親</h1><comp-child /></div>' }) Vue.component('comp-child', { template: '<p>componentの子</p>' }) new Vue({ el: '#app' }) See the Pen Vue.js vueコンポーネント練習10 by morioka (@rm5912) on CodePen. 親から子へのデータの受け渡し 親コンポーネントから子コンポーネントへのデータの受け渡しにはpropsを使います。 javascript Vue.component('hello-world',{ template: '<h1>Hello World and {{ message }}</h1>', props: ['message'] html <div id="app"> <hello-world message="Hello Vue.js"></hello-world> <hello-world message="Hello Japan"></hello-world> </div> この場合親コンポーネントはmessage属性としてその値を渡します。 messageの値が親コンポーネントから子コンポーネントに渡されて表示されています。 See the Pen Vue.js vueコンポーネント練習9 by morioka (@rm5912) on CodePen. propsとは そうなんだ〜とは思っていただけたかと思いますが、いまいちそのpropsってなに?って方も多いと思います。 propsを利用することで親コンポーネントから子コンポーネントに値を渡すことができます。 値を渡すというと関数がありますが、関数に値を渡す時に引数を利用するのと同様にpropsでも引数のようにコンポーネントに対して値を渡すことができます。 コンポーネントへpropsを渡すことでコンポーネント内で決められた処理を行うことができます。 親のdataを子へ messageに直接、値を入れていましたが、 v-bindを使うと親コンポーネントのdataを子コンポーネントに渡すことができます。 inputTextを親コンポーネントのdataに追加します。 javascript Vue.component('hello-world',{ template: '<h1>Hello World and {{ message }}</h1>', props: ['message'] }) var app = new Vue({ el: '#app', data: { inputText: '' } }) html <div id="app"> <input type="text" v-model="inputText"> <hello-world v-bind:message="inputText"></hello-world> </div> v-modelディレクティブを使って双方向データバインディングしています。 入力すると即座に出力されているのがわかるかと思います。 See the Pen Vue.js vueコンポーネント練習11 by morioka (@rm5912) on CodePen. v-forでリストデータを子に渡す v-forを使うことで配列を子コンポーネントに渡すことができます。 javascript Vue.component('flamework',{ template: '<div><h2>{{ flame.title }}</h2><p>{{ flame.content }}</p></div>', props: ['flame'] }) new Vue({ el: '#app', data: { flames: [ {'id':0, 'title': 'vue.js', 'content': 'JavaScriptフレームワーク'}, {'id':1, 'title': 'Rails', 'content': 'Rubyフレームワーク'}, {'id':2, 'title': 'Laravel', 'content': 'PHPフレームワーク'}, ] } }) 子コンポーネントはflameをオブジェクトとして受け取りtemplate内でflameの展開を行なっています。 html <div id="app"> <flamework v-for="flame in flames" v-bind:key="flame.id" v-bind:flame="flame"></b> </div> v-bind:keyを設定しないとエラーになりますので設定しましょう。 See the Pen Vue.js vueコンポーネント練習12 by morioka (@rm5912) on CodePen. またオブジェクトではなく、変数としても渡すことができます。 See the Pen Vue.js vueコンポーネント練習13 by morioka (@rm5912) on CodePen. 子から親へイベントを送る 親から子へはv-bindとpropsを使います。 子から親へのデータの受け渡しは$emitというメソッドを使います。 まずは$emitを理解するためにイベントを渡してみます。 アラートが発生するイベントを作成します。 javascript Vue.component('emit-event, { template: '<button v-on:click="clickEvent">ボタン</button> クリックイベントが発火したら、子コンポーネントはそのイベントの処理で$emitを実行して親に渡したいイベントを発火させます。 javascript methods: { clickEvent: function(){ this.$emit('from-child') } } 親は子から来るイベントに対するメソッドを設定して子から来るイベントを待ちます。 html <div id="app"> <emit-event v-on:from-child="alertMessage"></emit-event> </div> javascript var app = new Vue({ el: '#app', methods:{ alertMessage: function(){ alert('子からイベント受け取ったよ') } } }) 親は子が発生したイベントを受け取って親が用意していたメソッドを実行します。 ややこしいですね。 See the Pen Vue.js vueコンポーネント練習14 by morioka (@rm5912) on CodePen. また子コンポーネントでそのまま$emitをtemplateに書くこともできるようです。 その場合はmethodsを書く必要がなくなります。 javascript template: `<button v-on:click="$emit('from-child')">ボタン</button>`, 子から親へデータを渡す 次は子コンポーネント側のdataを親側に送る処理をしてみます。 子コンポーネントに入力フォームを作成して入力後に送信ボタンを押すとイベントが発火して $emitメソッドを使って入力した内容を親コンポーネントに送ります。 javascript Vue.component('emit-event',{ template: `<div> <input type="text" v-model="inputText"> <button v-on:click="clickEvent">送信ボタン</button> </div>`, data: function(){ return { inputText : '' } }, methods: { clickEvent: function(){ this.$emit('from-child',this.inputText) } }, }) $emitは引数を取ることができます。 引数を利用してデータを送ります。また複数のデータを渡す場合はオブジェクトを利用して渡すことができます。 html <div id="app"> <p>{{ message }}</p> <emit-event v-on:from-child="receiveMessage"></emit-event> </div> 入力されて受け取ったデータをdataのmessageに設定します。 javascript var app = new Vue({ el: '#app', data: { message: '' }, methods:{ receiveMessage: function(message){ this.message = message; } } }) See the Pen Vue.js vueコンポーネント練習15 by morioka (@rm5912) on CodePen. 子コンポーネントのフォームに入力されたテキストが親コンポーネントに渡されて、表示されています。 終わりに コンポーネントについてまとめてみました。 まとめたもののまだまだ理解が足りないなと感じています。。。 slotについてはまた次にまとめてみたいと思います。 参考サイト REFFECT vue.jsコンポーネントの基礎 Qiita [Vue.js]コンポーネントの親子関係とpropsについて Qiita propsと$emitでデータを引き渡す
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AlmaLinux8.3にvue-cli@2.9.6をインストールしてVue.jsを動かすまで

やりたいこと AlmaLinuxでVue.jsが使えるようにする。 前提 AlmaLinuxが最小構成以上でインストール済みであること。 root権限でSSH接続できること。 任意のユーザとホームディレクトリが作成済みであること。 サーバ環境 VirtualBox AlmaLinux-8.3-x86_64-dvd.iso インストール root権限で下記コマンドを実行する。 dnf update -y dnf install nodejs -y npm install -g @vue/cli バージョン確認 node -v npm -v vue --version Vueプロジェクト作成 任意のユーザ(ここではyamato)のホームディレクトリ配下に作成する。 su yamato cd /home/yamato/ プロジェクト名は vue_test_210428a とする。 vue create vue_test_210428a 実行後、 Your connection to the default npm registry seems to be slow. Use https://registry.npm.taobao.org for faster installation? (Y/n) Y と表示されるので、Y を入力する。エンターキーを押してからしばらく待つ。 ポート開放 vue起動時のデフォルトポート番号8080を開けておく。 root権限で実行する。 firewall-cmd --zone=public --add-port=8080/tcp --permanent firewall-cmd --reload 起動 cd vue_test_210428a/ npm run serve 画面表示 サーバのIPアドレスにhttpにてポート8080でアクセスして下記が表示されたらOK。 http://XXX.XXX.X.XX:8080/
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

vue-routerでリファラを取得する

前のページ情報を取得したいときに、vue-routerを使ってリファラを取得する方法について書きます。 ちなみにvue-routerを使ってるとJSのdocument.referrerでは正しい値を取れません。 本文 ルーティングファイル内でbeforeEachを定義して、リファラとなる値を保存する。 src/router/index.js const router = new VueRouter({ // ... }); router.beforeEach((to, from, next) => { router['referrer'] = from; next(); }) そうすると使いたいコンポーネントでリファラの値を取得することができる。 Hoge.vue <script> export default { method: { hoge () { let referrer = this.$router.referrer; console.log(referrer); } } }; </script> 補足 ちなみに特定のページでリファラを取得するこっち↓のやり方もある。 Vue.jsでアクセス元(referrer)を取得する │ エトセトラ備忘録 データ取得 | Vue Router 参考 Vue.js - VueRouterで前のページのURLを取得することは可能でしょうか?|teratail ナビゲーションガード | Vue Router ナビゲーションガードについてもうちょっと勉強せねば・・・ 間違いなどあったらご指摘ください。 おしまい
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

tailwind対応のVueのコンポーネントライブラリ

みなさんtailwind使ってますか? tailwindの良さって、CSSを書かずにクラスで定義できるので、CSSの運用コストや設計に時間が取られなく済むことですよね。 一方、その反面でVuetifyみたいにコンポーネント用意してくれていないため、結構1からコンポーネント作成することが多いと思います。 tailwind対応のコンポーネントないのかなと思って、探したけど見つける結構大変だったのでまとめていきます。 あんまり、見つけられなかったのでテンプレート集も追加しています。 コンポーネントフレームワーク DaisyUI 少し丸み帯びた可愛らし目のデザイン。Vue2にも対応しているためNuxtユーザーもで利用できます。 [VueTailwind](https://www.vue-tailwind.com/) Vue3対応なので、Nuxtユーザーはそのままでは使用できません。 テンプレート集 Tailblocks tailwindベースのテンプレート集。LPなど作るときに便利 Tailwind UI Kit tailwindベースのテンプレート集。Tailblocksよりもボタンやカードのパーツが多め tailwind components tailwindのサンプル集。自作したテンプレートをアップロードできるので、様々なテンプレートを見つけることができる。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

'v-slot' directive doesn't support any modifierエラーの対処方法。

'v-slot' directive doesn't support any modifierとエラーが出たときの対処方法。 [vue/valid-v-slot] 'v-slot' directive doesn't support any modifier. xxx.vue With Eslint error <template v-slot:item.name="{ item }"> xxx.vue Without error: <template v-slot:[`item.name`]="{ item }"> で解決
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む