20210507のvue.jsに関する記事は27件です。

render関数理解のための仮想DOM

初めにDomとはDocment Object Modelのこと。 仮想DOMとはブラウザ上で保持しているDomをJavascript上で模倣して作って保持しているものをいう。 なせ仮想DOMが必要? 前提としてブラウザで保持しているDOMのデータを更新するには時間がかかる。(パフォーマンスが落ちる) 次に 表示画面を考えてどういうアルゴリリズムであれば効率的に画面表示の変更ができるのか? ⇨変更前と変更後のDOMを比べてその差分だけを変更するアルゴリズムを考える。 ここで変更前の差分を作る前にブラウザ上のDOMを取得して行うとめちゃめちゃ時間を食うので自前でjavescript,vuejs内部で作って差分を取るのはさほど時間はかからないで行える。 ということは自前に変更前仮想DOMと自前の変更後仮想DOMを比べる方法をとってブラウザには差分のみの変更データを渡すようにする。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【初心者向け】Windows10でNode.jsとnpmをポータブルに活用する方法

ローカル環境を構築するのに、いまだに苦労している私です。 最近Vue.jsでの実装のため、Node.jsとnpmをポータブルバージョンで環境構築しました。 何とか構築は終わったのですが、やり方を忘れてしまいそうだったので、ここに手順をまとめてみました。 かなり初心者向けなので、予めご了承ください。 そもそも、Node.jsとnpmは何者か? Node.jsとnpmについて、超ざっくりに説明すると、 Node.jsは、サーバーサイドで稼働するJavaScript nmpは、Node.jsのパッケージを管理するツール となります。 パッケージとは、元々用意されている便利な機能をまとめたものです。 Node.jsとnpmをダウンロードする まずは、Node.jsとnpmを使用できるようにします。 zipファイルをダウンロード Node.jsのダウンロードページにアクセスします。 今回はzip形式で取得したいので、「Windows Binary(.zip)」を選択します。 32-bitか64-bitにするかは、お使いのPC環境によって異なります。 ダウンロードしたzipファイルは、ローカルディスクのDドライブに解凍しておきます。 cmdファイルの作成 解凍したフォルダ内に、「任意の名前.cmd」のファイルを作成します。 ファイルは「エディタ」か「メモ帳」で作成してください。 作成したファイル内に、下記の記載をします。 任意の名前.cmd @echo off set PATH=%PATH%;%cd% set NODE_PATH=%cd%\node_modules\npm\node_modules;%cd%\node_modules\npm cmd このとき、「メモ帳」を使って保存する場合は、文字コードをANSIにしないと上手く機能しません。 文字コードを確認するには、ファイルの「名前を付けて保存」をクリックします。 表示されるポップアップの「保存」ボタンの横に、文字コードが表示されていますね。 コマンドプロンプトで操作 先ほど作成したcmdファイルをダブルクリックすると、コマンドプロンプト(黒い画面)が開きます。 ここで、下記のコマンドを入力し、バージョンが確認できれば問題ないです。 cmd node -v npm -v パッケージをインストールできるようにする パッケージをインストールするには、プロキシ設定をする必要があります。 今回は、Vue.jsをインストールする際の手順をまとめます。 コマンドプロンプトで操作 先ほど作成したcmdファイルをダブルクリックして、コマンドプロンプトを出します。 コマンドプロンプトを立ち上げたら、下記のコマンドを入力します。 cmd npm -g config set proxy http://プロキシサーバアドレス:ポート npm -g config set https-proxy http://プロキシサーバアドレス:ポート npm -g config set registry http://registry.npmjs.org/ ご自身のプロキシサーバアドレスとポートの調べ方については、こちらが参考になります。 環境変数を設定 続いて、環境変数の設定方法です。 環境変数とは、OSそのものが持っている変数のことです。 [Windows]+[R]キーで「ファイル名を指定して実行」を表示させます。 そして、「sysdm.cpl」と入力して実行します。 システムのプロパティが表示されますので、詳細設計タブをクリックします。 そして、詳細設定タブの下にある「環境変数」ボタンを押します。 「環境変数」画面が表示されると、ユーザ環境変数とシステム環境変数の2種類があります。 ここでは、ユーザ環境変数に「新規」ボタンで、下記の変数と値を追加します。 HTTP_PROXY http://プロキシサーバアドレス:ポート HTTPS_PROXY http://プロキシサーバアドレス:ポート 表にすると、次のような感じです。 変数名 値 HTTP_PROXY http://プロキシサーバアドレス:ポート HTTPS_PROXY http://プロキシサーバアドレス:ポート HTTP_PROXYとHTTPS_PROXYは、プロキシ設定やnpmで使用する変数です。 次に、ユーザ環境変数にPathという変数が登録されているかと思います。 Pathは、Node.jsコマンドを利用できるようにするための変数です。 Pathを選択し、「編集」ボタンを押します。 「環境変数名の編集」画面が表示されたら、「新規」ボタンを押して、Node.jsの解凍ファイルが格納されているフォルダのパスを追加してください。 例えば、D:¥〇〇〇のような感じです。 Vue.jsをインストール 最後に、コマンドプロンプトに下記のコマンドを入力して、Vue.jsをインストールします。 cmd nmp install -g @vue/cli npm install -g @vue/cli-service-global 無事インストールされているか、下記のコマンドでバージョン確認してみましょう。 vue -V Vue.jsのインストールがうまくいかない場合は、IEを起動し、Google画面を開いてから、コマンドプロンプトでインストールのコマンドを入力してみてください。 こうすることで、プロキシの認証ができるようになります。 終わり これで、Windows10でNode.jsとnpmをポータブルに活用する方法のまとめは以上になります。 ローカル環境を立ち上げるのにも一苦労しますね…。 なので、こうして手順をまとめる機会があって良かったです。 ここまで読んでいただき、ありがとうございました。 参考記事
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

templateプロパティ

短いものなら(4行にわたってとかみたいに)tempeteプロパティにタグごと書いてviewで表示できます。 <!DOCTYPE html> <html lang="en"> <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> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app1"></div> <script> var vm1 = new Vue({ el: '#app1', data: { message: 'こんにちは' }, template: '<p>●●さん{{message}}</p>' }) </script> </body> </html>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

$mount

$mountは後付けでvueインスタンス内部のelを設定したい場合に使います。 <!DOCTYPE html> <html lang="en"> <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> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app1"> <p>{{message}}</p> <p>{{name}}</p> </div> <script> var data = { message: 'こんにちは', name: '前田' } var vm1 = new Vue({ data: data }) vm1.$mount('#app1') </script> </body> </html> 以下も同じになります <!DOCTYPE html> <html lang="en"> <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> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app1"> <p>{{message}}</p> <p>{{name}}</p> </div> <script> var data = { message: 'こんにちは', name: '前田' } var vm1 = new Vue({ data: data }).$mount('#app1') </script> </body> </html>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

$dataでvueインスタンスで取得できるものを表示させる

console.logを使ってvm.$dataとするとvueインスタンスで取得できるものを表示できます。 <!DOCTYPE html> <html lang="en"> <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> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app1"> <p>{{message}}</p> <p>{{name}}</p> </div> <script> var data = { message: 'こんにちは', name: '前田' } var vm1 = new Vue({ el: '#app1', data: data }) console.log(vm.$data) </script> </body> </html>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

インスタンス外からdataを設定する

<!DOCTYPE html> <html lang="en"> <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> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app1"> <p>{{message}}</p> <p>{{name}}</p> </div> <script> var data = { message: 'こんにちは', name: '前田' } var vm1 = new Vue({ el: '#app1', data: data }) </script> </body> </html>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Vue のリアクティブシステム

vueのリアクティブシステムとは new Vue({ el: '#app', data: { fruits: ['りんご','バナナ','キィウイ'] }, methods:{ remove: function(), this.fruits.shift() } } }) 配列の中身を変えるとそれに従って表示されるフルーツの中身も変わるということ。 ここからわかるルール。 リアクティブさせたいのなら初めからデータ内部にリアクティブにしたいプロパティを含めておくこと。 viewはviewインスタンスを見渡してそこにあるプロパティに対してsetterとgetterを用意する。 以下のインスタンスのvm1をコンソールで中身を見てみる。 <!DOCTYPE html> <html lang="en"> <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> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app1"> <p>{{message}}</p> </div> <script> var vm1 = new Vue({ el: '#app1', data: { me ssage: 'app1' } }) console.log(vm1) </script> </body> </html> のぞくと 下の方に get message set message があるのがわかる。これによってリアクティブシステムは動いてます。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

GASでWebアプリ「映画鑑賞記録」を作る⑩

今回やること  ダイアログボックスの「初見」の入力項目を、ラジオボタンに変更します。 ダイアログボックスの「初見」を変更 modalScript.html  テキストボックス(<input type="text"…>)をラジオボタン(<input type="radio"…>×2)に変更します。  本項目への入力値は、1が「初めて観た」で、0が「既に鑑賞した事がある」です。  ラジオボタンのラベル(<label>タグ)は、前者をはい、後者をいいえとします。  データのバインドは、テキストボックスの時と同様にv-model="cond.firstLook"で行います。 <script type="text/x-template" id="modal-template"> <transition name="modal"> : <div class="form-group"> <div class="input-group"> <label for="first-look" class="col-form-label">初見:</label> <!-- <input type="text" class="form-control" id="first-look" v-model="cond.firstLook"> --> <input type="radio" name="first-look" class="form-control" id="first-look-yes" v-model="cond.firstLook" value="1"> <label for="first-look-yes" class="form-control" style="border: 0px;">はい</label> <input type="radio" name="first-look" class="form-control" id="first-look-no" v-model="cond.firstLook" value="0"> <label for="first-look-no" class="form-control" style="border: 0px;">いいえ</label> </div> </div> : </transition> </script>  <label>タグは、class="form-control"により枠線が表示されるので、style="border: 0px;"を指定して非表示にします。   ◆style指定なし        ◆style指定あり       ◆参照サイト Vue.js 公式サイト フォーム入力バインディング 結果  「初見」がラジオボタンに変更されました。 ◆前の記事 GASでWebアプリ「映画鑑賞記録」を作る⑨ ◆索引 GASでWebアプリ「映画鑑賞記録」を作る《索引》
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

別のインスタンスからメッセージを変更する

Vue.jsではルートVueインスタンスを作成することで起動されます。 別のインスタンスからアクセスしてメッセージを変更するには関数を使って値を生成して代入してあげる。 var vm = new Vue({ // オプション }) varvm=newVue({ // オプション }) *vmはViewModelの意味であり、MVVMパターンの影響を受けているとのこと。 *varは変数の宣言で「var 変数名 = 値」となる。 <!DOCTYPE html> <html lang="en"> <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> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app1"> <p>{{message}}</p> </div> <div id="app2"> <p>{{message}}</P> <button @click="changeMessage1">メッセージ変更</button> </div> <script> var vm1 = new Vue({ el: '#app1', data: { message: 'app1' } }) var vm2 = new Vue({ el: '#app2', data: { message: 'app2' }, methods: { changeMessage1: function() { vm1.message = 'インスタン2から変えました' } } }) </script> </body> </html> 実行すると
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

newインスタンスを2つ設置する

<!DOCTYPE html> <html lang="en"> <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> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app1"> {{message}} </div> <div id="app2"> {{message}} </div> <script> new Vue({ el: '#app1', data: { message: 'app1' } }) new Vue({ el: '#app2', data: { message: 'app2' } }) </script> </body> </html> 以下のようになります。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

v-forの利用上での注意点

v-forディレクティブは要素の移動を最小限に抑えるアルゴリズムを使用し、可能な限りその場で同じタイプの要素を再利用しようとする。 結論 →v-forは予期しないエラーが起こるので必ずユニークなkey属性と共に用いましょう。 この内容をプログラムで表したいと思います。 <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <ul> <div v-for="fruit in fruits"> <p>{{fruit}}</p> <input type="text"> </div> </ul> <button @click="remove">先頭を削除</button> </div> new Vue({ el: '#app', data: { fruits: ['りんご','バナナ','キィウイ'] }, methods:{ remove: function(){ this.fruits.shift() } } }) 実行すると 問題点 インプットボックス内にそれぞれ上記を表す英語を入れて削除を実行すると 括弧内の表示が削除されずにずれます。 1.配列要素の'りんご','バナナ','キィウイ'についてはりんごが削除されて、りんごがバナナに置き換わり、バナナがキィウイに置き換わっている。 2.inputタグ内部は「可能な限り同じタイプ(inputタグ同士)の要素は再利用しようとする」でAppleが再利用され、Bananaが再利用されている。 この問題を解決する方法「Key」属性をあたえる <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <ul> <div v-for="fruit in fruits" v-bind:key="fruit"> <p>{{fruit}}</p> <input type="text"> </div> </ul> <button @click="remove">先頭を削除</button> </div> or <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <ul> <div v-for="fruit in fruits" :key="fruit"> <p>{{fruit}}</p> <input type="text"> </div> </ul> <button @click="remove">先頭を削除</button> </div> 利用上での注意点 (1)indexは使用しない。なぜか?りんごが削除されたときにバナナのインデックスが「1」から「0」になるのでユニークな値ではないため。 (2)テンプレートタグでは使用しない。テンプレートタグは表示されない「pisplay: noneの適用」だけで残っているため削除には用いない。 (3)配列内でりんごが2回登場する場合はユニークとならないので、配列ではなくオブジェクトとしてオブジェクト.idをkeyに利用することを考える。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

v-forに整数値を置いてみた

<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <ul> <li v-for="n in 10">{{n}}</li> </ul> </div> *in を ofに変えてもきちんと動きます。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

divタグを使わずに表現

HRタグはHorizontal Ruleの略で水平の罫線を表します。 <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <template v-for="fruit in fruits"> <ul> <li>{{fruit}}</li> <hr> </ul> </template> </div> new Vue({ el: '#app', data: { fruits: ['りんご','バナナ','キィウイ'] } })
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

v-forでオブジェクトを表示

オブジェクトとは 全てのデータはオブジェクトです。配列やHash、数字や文字列も、オブジェクトです。 <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <ul> <li v-for="value in object">{{ value }}</li> </ul> </div> new Vue({ el: '#app', data: { object: { firstName: '太郎', lastName: '田中', age: '20才' } } }) 表し方 v-for 適当に名前をつけて(valueで) in 設定オブジェクト名 *firstName,lastName,ageがキーで太郎,田中,20才がバリューと言います。 第2引数を表現 <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <ul> <li v-for="(value, key) in object">{{key}},{{ value }}</li> 第1引数 第2引数 </ul> </div> 第3引数を取得 <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <ul> <li v-for="(value,key,index) in object">({{index}}){{key}},{{ value }}</li> </ul> </div>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Vue.js 勉強メモ】computedとwatchの使い分け

はじめに 仕事で使う事になったので1からVue.jsについて学んだ。ちゃんと覚えておかないとまずそうな事を備忘録として1つ1つ残しておく。 computedとwatchの使い分け どちらも参照先の値(Vueインスタンスのdataプロパティの値)が更新された時に実行されるというのは同じだが、以下のように使い方に違いがある。 # 使い分け computed ・同期処理を実行する場合に使用(returnなので基本的には同期処理) ※ただし頑張れば非同期的な処理もできる watch ・非同期処理を実行する場合に使用・参照先の値を持つcomputedプロパティがHTML上に記載されていない時に使用 ※ただし、参照先の値が変更された時に・・・という場面で何らかの処理を実行する際のBest Practiceはcomputedを用いる事。どうしても対応不可能な場合にのみwatchを利用するようにするのがポイント。 参照先の値を持つcomputedプロパティがHTML上に記載されていない時に使用 の例 「参照先の値を持つcomputedプロパティがHTML上に記載されていない時」とは、 Vueインスタンスのdataプロパティのある値が更新された時に何かを実行したいが、その値を依存関係に持つcomputedプロパティがHTML上に存在せず、それ(computed)が動作しないため、値が変更されても何も処理が実行できないといった場合の事。 この動画で、 Vueインスタンスのdataプロパティのある値 とはcounterの事であり、このcounterが変化した時に何かの処理を実行する事を想定してconsole.log()を実行している。 動画のソースコードは以下。 sample.html <body> <div id="app"> <p>{{ counter }}</p> <button @click="counter += 1">+1</button> <!-- 参照先の値を持つcomputedプロパティが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> ※上記のソースコードでは、VueインスタンスにlessThanThreeというcomputedプロパティが定義されているが、それがHTML上には記載されておらず(コメントアウトされており)computedが動作していない状態になっている。 同期・非同期 の例 この動画は、counterが変更された場合にwatchが動き、変更の3秒後にcounter=0にする処理を実行したもの。computedは同期で、watchは非同期でそれぞれ処理されている。 動画のソースコードは以下。 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 () { console.log('同期'); return this.counter > 3 ? '3より上' : '3以下'; } }, watch: { counter: function () { const vm = this; setTimeout(function () { console.log('非同期'); vm.counter = 0; }, 3000) } } }) </script> </body> ※上記でconst vm = this;としている理由はこちらを参照 Vue.jsの勉強メモ一覧記事へのリンク Vue.jsについて勉強した際に書いた備忘録記事のリンクを集約した記事。 https://qiita.com/yuta-katayama-23/items/dabefb59d16a83f1a1d4
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

バックエンド(django)とフロントエンド(vuejs)の間でデータをやり取りするときに発生するCORSエラー

Access to XMLHttpRequest at 'http://localhost:8080' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status. APIサーバーとWebサーバーをそれぞれ別のポートで立てている場合に生じるエラーである。 このエラーはブラウザーのセキュリティのためのエラーなのでヘッダーに許可を与える必要がある。 今回の場合でいうとvue.js(localhost8080)からDjango(localhost:8000)へAPIリクエストを投げたときに起きるエラーです。 CORSの対策 Djangoに対してCSRF対策を行う。 Githubによると ・python -m pip install django-cors-headers ・INSTALLED_APPSにcorsheadersを追加 ・MIDDLEWAREにもレスポンスを追加 ・CORS_ORIGIN_ALLOW_ALL=Trueにする この事によりアクセス許可を送ることができ正常にデータを送信することができる。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【個人開発】旅行の記録・共有サービス『TriSto』をリリースしました

はじめに 訪れた場所、使った金額、移動手段等を記録することで旅行の詳細を体系的にまとめることができる旅行の記録・共有サービス『TriSto』をリリースしました。 私は旅行に行った際、次の旅行の参考にしたり、思い出にふけったりするために、旅行の記録をスマホにメモしていたのですが、より詳細かつ体系的に記録をまとめたいという思いから、本サービスを開発いたしました。 私のようにとにかく事細かに旅行の記録を残したいという方や、他人の旅行記録を参考にしたいという方に、本サービスを活用して頂ければ幸いです。 サービス概要 旅行が好きな人に 旅行の記録を詳細に残せる場を提供する 旅行記録・共有サービス アプリURL:https://www.tristo.work/ GitHubリポジトリ:https://github.com/Manabu-Ito9772/tristo ターゲット 旅行の記録を詳細に残しておきたい方 他人の旅行記録を参照したい方 ユーザーが抱える課題 自分が行った旅行を詳細かつ分かりやすくまとめたい。 実際に旅行に行ってきた人の情報を、自分の旅行計画の参考にしたい。 望む未来 旅行の詳細情報を記録したり、他者の旅行記録を参考にしたりすることで、旅行好きの人がより良い旅行を実現し、さらに旅行を好きになってくれることを願っています。 旅行記録作成方法 1. ペンアイコンをクリック 2. 旅行の概要を入力して「詳細入力ページへ進む」をクリック 3. 詳細入力ページで日付ごとにブロックを追加 4. ブロックを追加できたら「投稿する」をクリック 5. 旅行記録が作成されタイムラインに投稿される ※タイムラインの旅行記録のタイトルをクリックすることで詳細を確認できる 使用技術 バックエンド Ruby 2.6.5 Rails 6.1.3.1 RSpec 3.10.1 主要なGem sorcery 0.16.0 jwt 2.2.2 active_model_serializers 0.10.12 kaminari 1.2.1 rails_admin 2.0.2 rspec-rails 5.0.1 ER図 フロントエンド Vue 2.6.12 axios 0.21.1 vue-router 3.5.1 vuex 3.6.2 vuex-persistedstate 4.0.0-beta.3 vue-mq 1.0.1 mobile-device-detect 0.4.3 vee-validate 3.4.5 vue-select 3.11.2 vue-dropdown-menu 0.1.4 vuejs-datepicker 1.6.2 vue2-timepicker 1.1.6 moment 2.29.1 vue-infinite-loading 2.4.5 vue-loader 15.9.6 vue-js-modal 2.0.0-rc.6 v-scroll-lock 1.3.1 vue-fontawesome 2.0.2 bootstrap 4.5.3 インフラストラクチャー Nginx 1.12.1 Unicorn 6.0.0 AWS VPC EC2 Amazon Linux 2 RDS MySQL 5.7.26 S3 ALB Route53 ACM インフラ構成図 工夫したところ 直感的なUI/UX 説明書がなくても直感的に操作できるシンプルで分かりやすいUI/UXにすることを心がけました。 SPA VueによるSPAを採用することで、さくさくとストレスなく操作できようにすることを心がけました。 レスポンシブデザイン スマートフォンでは指の位置を考慮してメニューバーをフッターに表示するなど、媒体ごとの使いやすさの違いを意識したレスポンシブなデザインにするように心がけました。 苦労したところ javascript 主にVueによる開発だったのですがあまりjavascriptの知識がなかったので、少し複雑な処理を実装する際に手間取りました。ただ、Rubyを学習済みであったためか、割とすんなり文法は理解できたので、開発の後半はjavascriptで詰まるということはほとんどありませんでした。 レイアウト 事前に作成した画面遷移図の通りにレイアウトを組み立ててもしっくりこないことが多く、納得のいくレイアウトができるまでだいぶ時間がかかりました。 学んだこと ググり方 普通にググって知りたいことを知れなかったときに、別のフレーズでググったり、関連するフレーズでググったり、英語でググったりすることで答えにたどり着くことがあったので、「いかにググるか」が非常に重要であるということが分かりました。 とくに英語でググるというのが最も有効で、日本語ではヒットしないけど英語だとヒットするみたいなことが何回かありました。当たり前といえば当たり前ですが日本語より英語の情報の方が圧倒的に多いので、プログラミングに限らず英語でのググり方に慣れればかなり世界が広がると感じました。 ライブラリの活用 ある機能を自力で実装している最中に同じ機能を簡単に実装できるライブラリを発見し、一瞬で実装できたことがありました。事前に調べてから実装を始めなかったことを反省しています。 先人の知恵にあやかり、極力車輪の再発明をしないことを心がけようと思いました。 詰まったら一旦リフレッシュ エラー解決などで詰まってしまったときに、一旦昼寝したり別のことをしたりしてから再度問題に取り組むことですぐに問題が解決することがありました。詰まってイライラしているときに無理に解決しようとせず、一旦リフレッシュして凝り固まった脳をほぐすということがわりと有効であるということが分かりました。 今後実装したいこと / 改善したいこと 今のところ手動でテスト・デプロイしているので、CapistranoやCircleCIを活用してCI/CDパイプラインを確立したいです。 可読性が低いコードや重複コードをリファクタリングしたいです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

kintoneでVue.jsを使ってみる

今回はkintone + Vue.js で「Hello Vue!」してみたいと思います。 アプリの準備 公式ドキュメントを参考に 一覧と各レコードの詳細・追加・編集画面にHello Vue!を表示させます。 CDNはこちらから探してね! フォームの設定 スペースフィールドを一つ貼り付けます。 要素IDはspVueとしておきます。 一覧の設定 カスタマイズビュー、PC版とモバイル版で表示する を選択して、htmlは下記の様にします。 <div id="app"> {{ message }} </div> JavaScript 詳細・追加・編集画面表示イベントでは、スペースフィールドに先程のhtmlを追加します。 PC版とモバイル版でAPIがちょっとだけ違います。要注意! PC版 // 一覧画面表示 kintone.events.on(["app.record.index.show"], async (event) => { const app = new Vue({ el: "#app", data: { message: "Hello Vue!", }, }); return event; }); // 詳細・追加・編集画面表示 kintone.events.on( [ "app.record.detail.show", "app.record.create.show", "app.record.edit.show", ], async (event) => { const sp = kintone.app.record.getSpaceElement("spVue"); const div = document.createElement("div"); div.id = "app"; div.textContent = "{{message}}"; sp?.appendChild(div); const app = new Vue({ el: "#app", data: { message: "Hello Vue!", }, }); return event; } ); モバイル版 APIのappの前にmobileが必要です。 // 一覧画面表示 kintone.events.on(["mobile.app.record.index.show"], async (event) => { const app = new Vue({ el: "#app", data: { message: "Hello Vue!", }, }); return event; }); // 詳細・追加・編集画面表示 kintone.events.on( [ "mobile.app.record.detail.show", "mobile.app.record.create.show", "mobile.app.record.edit.show", ], async (event) => { const sp = kintone.mobile.app.record.getSpaceElement("spVue"); const div = document.createElement("div"); div.id = "app"; div.textContent = "{{message}}"; sp?.appendChild(div); const app = new Vue({ el: "#app", data: { message: "Hello Vue!", }, }); return event; } ); JavaScriptファイル追加時の注意! kintone Tech Channel キンテク チャンネルを参考に開発環境を構築しました。 ローカルのjsファイルをいちいちアップロードすることなく、楽にkintoneアプリに適用することができる素敵な開発環境が出来上がります。 しかし、要注意! このようにローカルのjsファイルのままでは、 開発PC内のローカルファイルを見ている状態なので、開発PC以外からはファイルにアクセスできません。 ですので、他のPCやモバイル端末等で試す場合は、 ファイル自体をアップロードするか、モバイルからもアクセスできる場所のURLを設定するかにしましょう。 (2時間ほど気づけなくてアワアワしていました) 動作確認&まとめ というわけで、無事にVue.jsでHello Vue!することができました。 kintone開発環境でVue.jsの勉強をお手軽にできる環境も手に入れることができたような気がします。 PC 一覧 PC 詳細 PC 追加・編集 モバイル 一覧 モバイル 詳細 モバイル 追加・編集
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

v-app-varを位置固定する時にv-main上に自動でpaddingを入れるようにする

Vuetifyのv-app-barをabsoluteやfixedで上に配置する時に v-app-barとv-mainを使いレイアウトを作る時v-app-barの部分が上に来て、v-mainの上の部分が重なってしまいます。 <template> <v-app> <v-app-bar id="app-bar" absolute> <v-app-bar-title>タイトル</v-app-bar-title> </v-app-bar> <v-main> <v-container> <nuxt /> </v-container> </v-main> </v-app> </template> このままではデフォルトではpaddingが0になってしまうのでclassを設定し、cssでpaddingを付け足さないといけません。 これを回避するためにv-app-barの属性にappを追加するとこで自動で丈夫にpaddingを追加してくれます。 <template> <v-app> <v-app-bar id="app-bar" absolute app> <v-app-bar-title>タイトル</v-app-bar-title> </v-app-bar> <v-main> <v-container> <nuxt /> </v-container> </v-main> </v-app> </template> うまく行きました、これで余計なcssを書かなくてすみますね。 参考:
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

v-for 識別子をとる

<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <ul> <li v-for="(fruit, index) in fruits">({{index}}){{fruit}}</li> </ul> </div> new Vue({ el: '#app', data: { fruits: ['りんご','バナナ','キュウイ','ぶどう']} }) エイリアス ある対象や実体を、複数の異なるシンボルや識別子で同じように参照できるする仕組みを指す。別名。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

v-for:繰り返し処理

配列を取り出して表示せる方法 <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <ul> <li v-for="fruit in fruits">{{fruit}}</li> </ul> </div> new Vue({ el: '#app', data: { fruits: ['りんご','バナナ','キュウイ','ぶどう']} }) 表し方 <li v-for="fruit in fruits">{{fruit}}</li> v-for 単数形名詞 in 複数形名詞 {{単数形名詞}}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

v-show

v-ifディレクティブとv-showディレクティブが消えた場合両者に違いがあります。 <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <p v-if="ok">if</p> <p v-show="ok">show</p> <button @click="ok = !ok">ボタン</button> </div> new Vue({ el: '#app', data: { ok: true } }) v-ifの場合(検証画面で) <!---->になっている v-showの場合(検証画面で) showとなっている。 v-showとtemplateタグの相性の悪さ - ```vuejs テスト vuejs new Vue({ el: '#app', data: { ok: false } }) ``` templateとの相性の悪さ templateタグはok: falseを受けて消えるがv-showは元もとdisplay: noneで消えていて元は残っているのでテストだけ残ってしまう事になる。 2 if-elseにあたるものがない 3 表示コストが高い(表示しないものでもdisplay: noneで読み込んでいる) *v-ifも<!---->要素を消す作業をしているのでこちらも表示コストが高い。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

templateタグの使用

<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <template> <p v-if="ok">OK</p> <p v-else>NG</p> </template> </div> templateタグは表示されない性質を持っている。 そこで連続した値を消すということが必要になった場合 <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <p v-if="ok">OK</p> <p v-if="ok">おはよう</p> <p v-if="ok">こんにちは</p> <button @click="ok = !ok">ボタン</button> </div> new Vue({ el: '#app', data: { ok: true } }) ボタンを押すと templateタグを使っても同じ挙動が起こせる。(グループで条件分岐させるときに便利) <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <template v-if="ok"> <p>OK</p> <p>おはよう</p> <p>こんにちは</p> </template> <button @click="ok = !ok">ボタン</button> </div> new Vue({ el: '#app', data: { ok: true } })
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ページトップリンク+スムーススクロール

概要 下記4つの方法で実現します jQuery CSS JavaScript JavaScript+Vue.js jQueryでの実現方法 参考書籍 動くWebデザイン アイディア帳 実現方法 ページトップリンク aタグでトップ(#)にリンクする -----省略----- <p id="page-top"><a href="#">Page Top</a></p> ページトップリンクをクリックするとjQuery animate scrollTop:0 へ移動させる $('#page-top').click(function () { $('body,html').animate({ scrollTop: 0 }, 500); return false; }); 結果 思った通りに動作しました return falseの意味は下記で確認しました 【JavaScript】return falseの意味について総まとめ。コード付で解説 CSSでの実現方法 参考 CSSのみ!簡単にスムーズスクロールを導入する htmlはjQueryの場合と同じです html { scroll-behavior: smooth; } 結果 思った通りに動作しました 注意点 Safari、Opera、IEには対応していません JavaScriptでの実現方法 参考 【脱jQuery】Javascriptのみでスムーススクロールを実装【コピペ】 htmlの内容はjQueryに加えてid要素を付与 -----省略----- <p id="page-top"><a id = "page_top_link" href="#">Page Top</a></p> JSでaタグのクリックでスムースクロールする ※思っていたより簡単 const smoothScrollTrigger = document.getElementById("page_top_link"); smoothScrollTrigger.addEventListener('click', function(e) { e.preventDefault(); window.scrollTo({ top: 0, behavior: 'smooth', }); }); JavaScript+Vue.jsでの実現方法 htmlはクリックイベント追加 <footer id="footer"> <p id="page-top"><a v-on:click = "page_top_click" href="#">Page Top</a></p> -----省略----- </footer> var footer = new Vue({ el:"#footer", methods:{ page_top_click:function(e){ e.preventDefault(); window.scrollTo({ top: 0, behavior: 'smooth', }); } } })
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Vueを触り始めてわからなかったヤツら

エンジニア見習いとして働き始めて2ヶ月が経ちました。 雰囲気でVue.jsに触れ始めてきましたが、コードをぱっと見てもわからなかった部分を書き綴っていきたいと思います。 そもそもJavaScriptも初心者レベル。 ※随時加筆予定 1. v-bindとv-onの省略記法(「:」と「@」に注意) v-bind <!-- 省略無し --> <input v-bind:value="message"> <!-- 省略した記法 --> <input :value="message"> v-bindディレクティブは、リアクティブにHTML属性を更新します。 ※ディレクティブ・・・v-から始まる特別な属性のこと。 ※リアクティブ・・・データ変更がリアルタイムでビュー側に反映されること。 ※バインディング・・・結び付け、関連付けみたいな意味。 "message"は文字列ではなくJavaScript。 v-on <!-- 省略無し --> <a v-on:click="doSomething"> ... </a> <!-- 省略した記法 --> <a @click="doSomething"> ... </a> v-on:イベント名="ハンドラ名" 2. ref について書く予定。 参考 Vue.js テンプレート構文
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel+Vue+MySQL+GitHubでHerokuに自動デプロイ! プロジェクト作成〜自動デプロイまで

概要 Laravelのプロジェクト作成しVueを導入する (リポジトリは分離させないのでVueCLI未使用) GitHubのmasterブランチにPush/MergeされたらHerokuに自動デプロイさせる データベースにはMySQLを使用 デプロイはCircleCI等のCIサービスは使用せずにHerokuのみで完結させる 開発環境 Laravel 7.30.4 Vue 2.6.12 MySQL 目次 Laravelプロジェクト作成Git設定 Vue関連インストール&設定 Laravel側のHeroku設定 Herokuアプリ, MySQL作成 Heroku自動デプロイ設定 1. Laravelプロジェクト作成&Git設定 ①GitHubのリモートリポジトリ作成 ②Laravelプロジェクト作成 composer create-project --prefer-dist laravel/laravel blog "7.*" ③ルーティング設定 Vue-RouterでSPAにするので下記のLaravel側のルーティングは初回のアクセスに対するもの web.php Route::get('/{any?}', function () { return view('index'); })->where('any', '.+'); ④初回アクセス時のblade作成 views/index.blade.php <!doctype html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>{{ config('app.name') }}</title> <!-- Scripts --> <script src="{{ mix('js/app.js') }}" defer></script> <!-- CSS --> <link rel="stylesheet" href="{{ mix('css/app.css') }}"> </head> <body> <div id="app"> <router-view></router-view> </div> </body> </html> 下記のGit設定は必要に応じて行ってください ⑤Git初期化&リモートリポジトリ設定 git init git remote add origin https://github.com/*********/*********.git ⑥masterブランチにFirstCommit git add . git commit -m "first commit" git push origin master ⑦developブランチ作成&リモートリポジトリにプッシュ git checkout -b develop git push origin develop これでGit関連の基本的な設定終了 2. Vue関連インストール&設定 ①Vueインストール composer require laravel/ui "2.*" php artisan ui vue ※laravel7の場合2.*が対応しているバージョン ②Vue-Routerインストール npm install vue-router ※必要に応じて ③Vuex, Vuetify, mdi/fontインストール npm install vuex npm install Vuetify npm install @mdi/font ④Home.vue, Router, Storeファイル作成 & インポート VueCLIで作成したわけではないのでrouterやstoreファイルを0から作成しなければなりません 下記はVueCLIで自動生成されるrouter,storeファイルをもとにしたベースを紹介します resources/js/views/Home.vue <template> <div>Home</div> </template> router/index.js import Vue from 'vue' import VueRouter from 'vue-router' import Home from '../views/Home.vue' Vue.use(VueRouter) const routes = [ { path: '/', name: 'Home', component: Home }, ] const router = new VueRouter({ mode: 'history', routes }) export default router store/index.js import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state: { }, mutations: { }, actions: { }, modules: { } }) main.js import router from './router' import store from './store' window.Vue = require('vue'); const app = new Vue({ router, store, el: '#app', }); 3. Laravel側のHeroku設定 ①Procfile作成 プロジェクトルートにHerokuアプリ起動時に実行されるコマンド及びプロセスの種類を定義するファイルを作成します Procfile web: vendor/bin/heroku-php-apache2 public ②package.json修正 Herokuデプロイ時にビルドさせるためのスクリプト記述 package.json "scripts": { "dev": "npm run development", "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --config=node_modules/laravel-mix/setup/webpack.config.js", "watch": "npm run development -- --watch", "watch-poll": "npm run watch -- --watch-poll", "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --disable-host-check --config=node_modules/laravel-mix/setup/webpack.config.js", "prod": "npm run production", "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --config=node_modules/laravel-mix/setup/webpack.config.js", + "postinstall": "npm run prod" }, ③Heroku用.envファイル作成 .envはデフォルトでgitの管理対象外なので本番環境用の.envを新規作成します ※デプロイ時には.envとして動かします cp .env .env.heroku composer.json "scripts": { "post-autoload-dump": [ "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump", "@php artisan package:discover --ansi" ], "post-root-package-install": [ "@php -r \"file_exists('.env') || copy('.env.example', '.env');\"" ], "post-create-project-cmd": [ "@php artisan key:generate --ansi" ], + "compile": [ + "@php -r \"file_exists('.env') || copy('.env.heroku', '.env');\"" + ] } 4. Herokuアプリ, MySQL作成 ①Create new appからアプリ作成に進む ②一意なアプリ名を入力してCreate App 何も入力しなかった場合は自動的にアプリ名が割り振られる これでアプリは作成はできたがdyno(コンテナ)は作成されていない状態となる Laravelのプロジェクトをデプロイしたらdynoが作られる ③Find more add-onsからMySQL作成に進む ④ClearDB MySQLを選択→install clearDB MySQL ⑤App to provision toにはアプリ名を入力しSubmit Order Form ※ここでエラーが発生した場合はAccountSettings->Billingからクレジットカードを登録しているか確認 PostgreSQLもMySQLも無料で使用できるがMySQLの場合はクレジットカード登録が必要 ⑥DBの接続情報確認 Reveal Config Varsを選択するとCLEARDB_DATABASE_URLの値が表示されます そこの値にはホスト名、ユーザー名、パスワード、DB名全てが記述されています 下記の書式を参考に各情報をひかえましょう mysql://ユーザー:パスワード@ホスト/DB名?reconnect=true ※Laravel側の.env.herokuにもDB情報を記述をしましょう 5. Heroku自動デプロイ設定 ①Deployment method項目のGitHubアイコンボタンを選択 デプロイの資材となるリモートリポジトリを選択します ②Enable Automatic Deploysで自動デプロイ設定 後はGitHubのmasterブランチにプッシュorマージすると自動デプロイされます おまけ php artisan migrateする heroku run php artisan migrate --app=アプリ名 SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long 上記エラーが出た際はcharasetを変更する config/database.php 'mysql' => [ 'driver' => 'mysql', 'url' => env('DATABASE_URL'), 'host' => env('DB_HOST', '127.0.0.1'), 'port' => env('DB_PORT', '3306'), 'database' => env('DB_DATABASE', 'forge'), 'username' => env('DB_USERNAME', 'forge'), 'password' => env('DB_PASSWORD', ''), 'unix_socket' => env('DB_SOCKET', ''), - 'charset' => 'utf8mb4', - 'collation' => 'utf8mb4_unicode_ci', + 'charset' => 'utf8', + 'collation' => 'utf8_unicode_ci', 'prefix' => '', 'prefix_indexes' => true, 'strict' => true, 'engine' => null, 'options' => extension_loaded('pdo_mysql') ? array_filter([ PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), ]) : [], ],
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Vue3でFontAwesomeを使ってみた

今回紹介するのはvue3でのFontAwesomeの利用方法です。 Vue3という新しいバージョンがリリースされてからまだ間も無く、参考記事がほとんどなかったため、 Vue3でFontAwesomeを利用するのに少し苦労しました。 皆さんの参考になれば幸いです。 FontAwesomeのインストール 作成したprojectに移動してインストールします。 $ npm install --save @fortawesome/fontawesome-svg-core #アイコンをインストール $ npm install --save @fortawesome/free-solid-svg-icons #Vue3で使用するためにインストール $ npm install --save @fortawesome/vue-fontawesome@prerelease アイコンは下記タイプがあります。必要に応じてインストールしてください。 ・Solid : 内塗り ・Regular : 線(内塗りの逆) ・Light : 細い線(有料プランのみ) ・Brands : ロゴ等 $ npm install --save @fortawesome/free-regular-svg-icons $ npm install --save @fortawesome/free-brands-svg-icons $ npm install --save @fortawesome/pro-regular-svg-icons main.jsに追加 Vueで使えるようにFontAwesomeをインポートします。 使いたいアイコンごとにインポートしてライブラリに追加します。 main.js import { createApp } from 'vue' import App from './App.vue' import './index.css' //ここから追加 import { faLeaf } from '@fortawesome/free-solid-svg-icons' import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome' library.add(faLeaf, faPencilAlt, faBook, faFacebook) //ここまで追加 var app = createApp(App) //コンポーネントの追加 app.component('fa', FontAwesomeIcon ) app.mount('#app') アイコンを使用 faタグを追加して、アイコン名を指定します. src/components/fontAwesome.vue <template> <div> <fa icon="leaf" /> </div> </template> 参考 [リンク]https://www.npmjs.com/package/@fortawesome/vue-fontawesome [リンク]https://qiita.com/kurararara/items/d76776a7dc2d763a068b
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む