- 投稿日:2019-07-11T23:23:32+09:00
初心者向け!vue.jsの開発環境の構築
はじめに
ここでは、
vue cli
を利用したvue.js
開発環境の構築を行っていきます。
すでにプログラミング経験が豊富な方は、公式のドキュメントを読んだりして問題なく環境構築ができると思います。しかしプログラミング未経験・新人エンジニアの方は環境構築だけでつまずいてしまうこともある事でしょう。参考にしている記事が古ければコマンドをマネしても上手くいかない事があり頭を抱えることも…そんな方たちに向けた記事となります。
筆者の環境はmac
です。windows
の方はもしかしたらどこかでエラーが出てしまうかもしれません。その場合コメント等で教えていただければ、今後見てくれる方の為に記事を修正致します。
では、vue.js
の環境構築をやっていきましょう。まずは準備
今回vueのインストールには
yarn
を使用します。
yarnのインストールにはnpmが必要で、npmの使用にはnode.jsのインストールが必要です。
必要な物を順番に揃えていきましょう。まずはnode.jsをインストール。
https://nodejs.org/en/
こちらからダウンロードします。ダウンロード前にOSが間違っていないか注意しましょう。node.jsをインストールすると、npmも一緒にインストールされます。以下のコマンドで確認してみましょう。
ターミナル$ node -v # node.jsのバージョン確認 v10.15.3 $ npm -v # npmのバージョン確認 6.4.1確認できました。
では続いてyarnをインストールしますが、windowsかmacかでちょっと方法が変わります。macの方はこちら。brewコマンドが使えない方はHomebrew ( https://brew.sh/index_ja ) をインストールしてください。
ターミナル$ brew update $ brew install yarnwindowsの方はこちらから
https://yarnpkg.com/lang/ja/docs/install/#windows-stable
一番上のインストーラをダウンロードし、起動するとコマンドを叩く事なくyarnをインストールできます。下二つの方法でももちろん構いません。お好みでどうぞ。正常にインストールされたか確認します。
ターミナル$ yarn -v # yarnのバージョン確認 1.16.0確認できました。これで準備は終了です。vueをインストールしていきましょう。
アプリケーションプロジェクトの作成
アプリケーションプロジェクトっていきなりよくわからない単語が出てきましたが、これから作るアプリのディレクトリ(フォルダ)を作るよ!的な意味です。
さっそくやっていきましょう。
まずはこの二つのコマンドをターミナルで打ち込んでください。ターミナル$ yarn global add @vue/cli $ yarn global add @vue/cli-initこれでvueの最新版がインストールされたはずです。確認してみましょう。
ターミナル$ vue --version # vue.jsのバージョンを確認 3.9.2最新版のvueがインストールされていることが確認できました。
続いてプロジェクト作成を行います。ここでは、vue-app
というプロジェクト名で作成します。ターミナル$ vue init webpack vue-app色々聞かれるはずです。何を聞かれているのかは今回割愛しますが、意味がわからない内はエンターキー連打で問題ありません。もちろん、後から
package.json
をいじることで変更することも可能なので安心しましょう。
全ての質問に答えるとインストールが始まります。インストール終了後、以下のような内容が出力されます。これで開発環境の構築は終了です。ターミナルRunning eslint --fix to comply with chosen preset rules... # ======================== > vue-app@1.0.0 lint D:¥vue-app > eslint --ext .js,.vue src test/unit test/e2e/specs "--fix" # Project initialization finished! # ======================== To get started: cd vue-app npm run dev Documentation can be found at https://vuejs-templates.github.io/webpackアプリケーションの起動確認
vue cli
を使用してアプリケーションプロジェクトの作成が終わりました。構築が正常に完了しているかどうか確認の意味も兼ねて、起動してみましょう。
まずは作成したアプリケーションプロジェクトへ移動します。ターミナル$ cd vue-app続いて必要な依存モジュールをインストールします。
ターミナル$ yarn install最後に開発モードでアプリケーションを起動します
ターミナル$ yarn dev次のような内容の出力がされたと思います。
ターミナルDONE Compiled successfully in 2820ms 10:39:56 I Your application is running here: http://localhost:8080ブラウザを開いて、出力に記載されている
http://localhost:8080
を入力してみましょう。
この画面が表示されたら無事、環境構築が終了しています。
お疲れさまでした。
- 投稿日:2019-07-11T21:00:29+09:00
firebase・vue.jsで作ったWebアプリにGoogle Analyticsを設定してみた。
やること
先日作ったwebアプリreftikaにGoogle Analyticsを設定する。
webアプリの詳細はこちらの記事を参照ください。
<初心者>レファレンス協同データベースの記事をランダムに表示するWEBサービスをvue.jsで作りました。やったこと
vue-routerを使っている場合は、やることは2つだけでした。
1.[Google Analytics]のページでアカウント作成
2.vue-analyticsの導入・設定参考:
Vue-SPAでもGoogle Analyticsしたい!
Vue.jsのプロジェクトでGoogleAnalyticsの設置1.Google Analyticsのページでアカウント作成
2.vue-analyticsのインストール・設定
インストール
npm install vue-analytics -save設定
main.jsに追記
main.jsimport VueAnalytics from 'vue-analytics' Vue.use(VueAnalytics, { id: 'UA-XXX-X' ←google analyticsのID })ES5の書き方の場合はmain.jsは以下のようにする。
main.jsconst VueAnalytics = require('vue-analytics').default Vue.use(VueAnalytics, { id: 'UA-XXX-X' ←google analyticsのID })以上でGoogle Analyticsのページに反映されます。
その他
上記でも使っているVue.use()ってそもそも何なのかという初歩的なことがあいまいだったのでメモ。
・Vur.use()はプラグインを使用するために使用する。
・プラグインとはVueにグローバル・メソッドやグローバル・アセット、コンポーネントアクションなどを追加するもの。
- 投稿日:2019-07-11T19:31:26+09:00
とあるVue Routingのインデックス
- 投稿日:2019-07-11T17:44:42+09:00
Vue.js用のVSCode設定
Vue.js用のVSCodeの設定はVueMasteryのこの動画がおすすめ。
- 投稿日:2019-07-11T17:30:41+09:00
Vue.jsでログイン画面作り続けないと発作が出るお話(環境構築編)
「...うぅ...つ...作りたい...作りたいぃ...」
「ログイン画面を...作りたいィィィィィィィィィ!!!!!」
すいません。唐突にログイン画面を作らないと発症する発作が出てしまいました。みやゆーです。
発作を収めるために早速ログイン画面を作っていきたいと思います。
どうやって発作を抑えるか
とはいえ、どのようにログイン画面を作っていくかが問題です。
今回の発作は急に発症し、症状も激しいので一刻の猶予もありません。
ここはサクッとページを作成していけるVue.jsと,導入やユーザー管理も簡単なFirebaseを使って作っていきましょう。
なぜVue.jsとFirebaseを使うのかは、それを説明しないと発症する発作が出れば説明します。強いて言えば「少しだけ知見があるから」。そんなもんです。
できるかな?じゃない、やるんだよ
早速やっていきましょう。まずは環境構築です。
環境構築
$ node -v v10.15.3 $vue -V 3.7.0 $ npm -v 6.4.1Vue-cliのバージョン確認は
-V
ね。小文字じゃないよ。んでVue-cliは、3.0以前と以降で若干インストールのコマンドが違うんですよ。
まだ導入してない人は気を付けてね!
パッケージのインストール
いわゆるログインページの"器"を作ります。
コンソールで今いる場所を確認してから作ってね。直下にプロジェクトファイルができます。
vue create login_test
なんか出てきた。
Vue CLI v3.7.0 ┌───────────────────────────┐ │ Update available: 3.9.2 │ └───────────────────────────┘ ? Please pick a preset: (Use arrow keys) > default (babel, eslint) Manually select featuresほーん。
default
かManually select features
を選べってか。
default
にはbabel
とeslint
しか入ってないのね。他にもいっぱいぶち込みたいので
Manually select features
を選びましょう。? Check the features needed for your project: (Press <space> to select, <a> to toggle all, <i> to invert selection) (*) Babel ( ) TypeScript ( ) Progressive Web App (PWA) Support ( ) Router >( ) Vuex ( ) CSS Pre-processors (*) Linter / Formatter ( ) Unit Testing ( ) E2E Testing必要なものにカーソルを合わせてスペースでチェックを入れていきましょう。
今のところ必要なのは以下の2つ。
- Router: ページ遷移するのに必要
- Vuex: 後述
Vuexについては後で説明しますがめちょめちょに大事なので絶対入れといてください。後からでも入れれるけどね。だるいので。
? Use history mode for router? (Requires proper server setup for index fallback in production) (Y/n)
Yesで大丈夫です。
? Pick a linter / formatter config: (Use arrow keys) > ESLint with error prevention only ESLint + Airbnb config ESLint + Standard config ESLint + Prettierこれも1番上で大丈夫。
? Pick additional lint features: (Press <space> to select, <a> to toggle all, <i> to invert selection) >(*) Lint on save ( ) Lint and fix on commit上でいいでしょう。
? Where do you prefer placing config for Babel, PostCSS, ESLint, etc.? (Use arrow keys) > In dedicated config files In package.jsonBabelとかESLintの設定をどこに置くか。私は全部package.jsonにまとめてあるほうが好きなので下ですね。ここら辺は全部好みです。
? Save this as a preset for future projects? (y/N)今後プロジェクトを作るときに今までの設定を反映させるか。んー...今回だけなのでNoで。
Vue CLI v3.7.0 ✨ Creating project in C:\Users\miyaji.yusei\Documents\login_test. ? Initializing git repository... ⚙ Installing CLI plugins. This might take a while... yarn install v1.15.2 info No lockfile found. [1/4] Resolving packages...
( ^ω^)おっ
インストール始まりましたね。
success Saved lockfile. Done in 14.09s. ⚓ Running completion hooks... ? Generating README.md... ? Successfully created project login_test. ? Get started with the following commands: $ cd login_test $ yarn serveインストール終わりっ!めっちゃ簡単。
これで環境が整いました!テンプレートができてるはずなので起動してみましょう!
$ cd login_test $yarn serve起動してくれます。。。
DONE Compiled successfully in 5902ms 17:43:36 App running at: - Local: http://localhost:8080/ - Network: http://192.168.116.39:8080/ Note that the development build is not optimized. To create a production build, run yarn build.起動完了!Vue.jsのlocalhostはデフォルトで8080です。chrome等でURLを叩きましょう。
localhost:8080
できた!あとはログイン画面を作るだけや!
まだまだ長いやんけ...
でも発作は収まったので良しとします。
また発症したら続きを描きます。みやゆーでした。
- 投稿日:2019-07-11T17:08:22+09:00
tiptapのコードブロックの下に空行を挿入する方法
- Vue: ^2.6.10
- tiptap: ^1.23.1
tiptapを使っていて、困ったことがありました。
tiptapを使えば、ハイライト付きのコードブロックが簡単に実装できます。
しかし、挿入されたコードブロックからカーソルを外すには、command+Z(macだと)するか、コードブロック以外の要素をクリックするかしかないみたいでした。
これだと、エディト領域の一番下にコードブロックが作られた場合に不便です。
コードブロックが挿入されたら、その下に空行を挿入することで、上記の問題を解決したので、共有します。editor.vue<template> <div class="editor" style="width: 100%;"> <editor-menu-bar :editor="editor" v-slot="{ commands, isActive }"> <div class="menubar"> <button class="menubar__button" :class="{ 'is-active-button': isActive.code_block() }" @click="startCodeBlock(commands, isActive)"> <font-awesome-icon icon="code" /> </button> </div> </editor-menu-bar> <editor-content class="editor__content" :editor="editor" /> </div> </template> <script> import { Editor, EditorContent, EditorMenuBar } from 'tiptap' import { safeInsert, findBlockNodes } from 'prosemirror-utils' import python from 'highlight.js/lib/languages/python' import { CodeBlock, CodeBlockHighlight } from 'tiptap-extensions' export default { components: { EditorContent, EditorMenuBar, }, data() { return { editor: new Editor({ extensions: [ new CodeBlock(), new CodeBlockHighlight({ languages: { python } }) ], content: ``, }), } }, beforeDestroy() { this.editor.destroy() }, methods: { startCodeBlock(commands, isActive) { commands.code_block() if (isActive.code_block()) { this.insertEmptyLineBelowCodeBlock() } }, insertEmptyLineBelowCodeBlock() { const { schema, state, view } = this.editor const selection = state.tr.selection const anchorPos = selection.$anchor.pos const blockNodes = findBlockNodes(view.state.doc) for (const { node, pos } of blockNodes) { // コードブロックの場所より下に何らかのnodeがある時は空行を挿入する必要がないので、return if (anchorPos < pos) { return } } // <p>をコードブロックの下にinsertする(https://github.com/atlassian/prosemirror-utilsのsafeInsertを利用) const p = schema.nodes.paragraph.create() view.dispatch(safeInsert(p, anchorPos)(state.tr)) // 選択カーソルをコードブロック内に戻す view.dispatch(view.state.tr.setSelection(selection)) } } } </script> <style> .ProseMirror pre { white-space: pre-wrap; width: 100%; } .editor__content pre { padding: .7rem 1rem; border-radius: 5px; background: #000; color: #fff; font-size: .8rem; overflow-x: auto; } .editor__content * { caret-color: currentColor; } .is-active-button { background-color: antiquewhite } </style>
- 投稿日:2019-07-11T12:57:47+09:00
【ヘルパー関数】ストアとコンポーネント間の通信
参考文献
Vue.js入門Vueインスタンスにstoreを渡してあるものとします。
ヘルパー関数
ヘルパー関数とは、コンポーネントからストアにアクセスする為の関数で下記の4つが用意されています。
・mapState
・mapMutations
・mapGetters
・mapActionsこれを使い、コンポーネントの算出プロパティやメソッドに結び付けられます。
比較のためにthis.storeを使った参照の例を書きます。
this.storeを使って参照
store.jsimport Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state: { count: 0 }, mutations: { increment: function(state) { state.count++ } } })App.vue<template> <div id="app"> <p>{{ count }}</p> <button v-on:click="increment(1)">add1</button> </div> </template> <script> export default { computed: { count: function() { //store内のcountのstateを渡す return this.$store.state.count } }, methods: { increment: function(value) { //ストア内の'increment'mutationをcommit this.$store.commit('increment', value) } } } </script>ヘルパー関数を使って参照
先ほどのApp.vueをmapStateとmapMutationsを使い記述した例です。
App.vue<template> <div id="app"> <p>{{ count }}</p> <button v-on:click="increment">add1</button> </div> </template> <script> // 'mapState'と'mapMutations'を使えるようにする import { mapState, mapMutations } from 'vuex' export default { // '$sotre.state.count'をthis.countと結びつける computed: mapState([ 'count' ]), // 'this.$store.commit('increment', value)'を、this.increment(value)で呼び出せる methods: mapMutations([ 'increment' ]), } </script>また、 下記のようにヘルパー関数の引数にオブジェクトを渡すと、コンポーネント上で
this.プロパティ名
で参照可能になります。App.jsimport { mapState } from 'vuex' export default { // '$sotre.state.count'をthis.valueと結びつける computed: mapState({ value: 'count' }) }ヘルパー関数は簡単にコンポーネントからストアを使うことができますが、これでは通常の算出プロパティやメソッドを書く場所がなくなります。
そのような場合、ヘルパー関数の戻り値と通常のこれでは通常の算出プロパティ・メソッドの定義を、オブジェクトスプレッド演算子やobject.assign関数で結合し、両方一度に使うことができます。下記はmapStateでstateのcountを結びながら通常の算出プロパティdoubleを定義しています。
App.vueimport { mapState } from 'vuex' export default { // 通常の算出プロパティを定義 computed: { double: function() { return this.conut * 2 }, // 通常の算出プロパティとmapStateの戻り値を結合 ...mapState([ 'count' ]) } }名前空間つきのモジュールは、ヘルパー関数の第一引数に名前空間の文字列を渡すことにより記述できます。
下記は、counter名前空間にあるcountをthis.countに結ぶ例です。App.vueimport { mapState } from 'vuex' export default { // '$store.state.counter.count'を'this.count'に結ぶ computed: mapState('counter',[ 'count' ]) }
以上です。
また学習が進み次第、更新、掲載していきます。
ここまでで補足や訂正などありましたらご教授いただけると嬉しいです。
最後まで読んでいただきありがとうございます。
- 投稿日:2019-07-11T12:54:38+09:00
Vue.js を勉強する Session�7
リストレンダリング
v-forで配列に要素をマッピングする
配列に基づいて、アイテムのリストをレンダリングするために、v-forディレクテイブを使用します。
v-forディレクティブはitem in itemsの形式で特別な構文を要求し、itemsは配列で、itemは配列要素を順不動で復されているエイリアスです。html部分<ul id="example"> <li v-for="item in items"> {{ item.message }} </li> </ul>javascript部分let app = new Vue({ el: '#example', data: { items: [ { message: 'item1' }, { message: 'item2' } ] } })ブラウザ画面・item1 ・item2上記の例ではitems配列の要素をブラウザ画面にレンダリングしています。
v-forブロック内では、親スコープのプロパティへの完全なアクセスを持っています。
またv-forは現在のアイテムに対する配列のインデックスを、2つ目の引数としてサポートしてます。html部分<ul id="example"> <li v-for="(item, index) in items"> [配列番号:{{ index }}] - [配列要素:{{ item.message }}] </li> </ul>ブラウザ画面・[配列番号:0] - [配列要素:item1] ・[配列番号:1] - [配列要素:item2]javascript部分は上記の例と同じです。
indexは配列の要素番号です。また、区切り文字としてinの他にofを使用することができます。
これはjavascriptのイテレータ構文に近いものです。オブジェクトのv-for
オブジェクトのプロパティに対して、v-forを使って反復処理する事ができます。
html部分<ul id="example"> <li v-for="value in object"> {{ value }} </li> </ul>javascript部分let app = new Vue({ el: '#example', data: { object: { title: '公式リファレンスをトレスしながら勉強', author: 'Sthudent Camilo', publishedAt: '2019-07-09' } } })ブラウザ画面・公式リファレンスをトレスしながら勉強 ・Sthudent Camilo ・2019-05-21オブジェクトでは2つ目の引数にプロパティ名(key)もサポートされています。
html部分<ul id="example"> <li v-for="(value, name) in object"> {{ name }} : {{ value }} </li> </ul>ブラウザ画面・title : 公式リファレンスをトレスしながら勉強 ・author : Sthudent Camilo ・publishedAt : 2019-07-09javascriptは上記の例と同じ
オブジェクトはindexもサポートされています。
html部分<ul id="example"> <li v-for="(value, name, index) in object"> {{ index }} . {{ name }} : {{ value }} </li> </ul>ブラウザ画面0 . title : 公式リファレンスをトレスしながら勉強 1 . author : Sthudent Camilo 2 . publishedAt : 2019-07-09【注意】
オブジェクトを反復処理するとき、順序はObject.keys() の列挙順のキーに基いており、全てのjavascriptエンジンの実装で一貫性で保証されていません。
状態の維持
※正直この題目はピンときていので理解が深まり次第追記します。
Vue.jsがv-forで描画された要素のリストを更新する際、標準では”その場でパッチを適応する”方法が用いられます。
データのアイテムの順序が変更された場合、アイテムの順序に合わせてDOM要素を移動する代わりに、Vueは各要素にその場でパッチを適応して、その特定のインデックスに何を描画するべきかを確実に反映します。html部分<ul id="example"> <li v-for="value in object" v-bind:key="value.id"> {{ value }} </li> </ul>繰り返されるDOMの内容が単純な場合や、性能向上のために標準の動作に意図的に頼る場合を除いて、可能なときはいつでもv-forにkey属性を与えることがベストプラクティスです。
詳しく書かれている記事
Vue.js: v-forで項目インデックスをkey属性にしていいのか【注意】
オブジェクトや配列のような非プリミティブ値をv-forのキーとして使わないでください。代わりに、プリミティブ値である文字列や数値を使ってください。
配列の変化を検出
変更メソッド
dataプロパティで宣言した配列に変更を加える配列メソッドは以下の通りです。
html部分<ul id="example"> <li v-for="item in items" v-bind:key="item.id"> {{ item.message }} </li> </ul>javascript部分let app = new Vue({ el: '#example', data: { items: [ { message: 'item1' }, { message: 'item2' } ] } })push()
配列の末尾に要素を追加します
開発者モードのConsoleapp.items.push({ message: 'item3' }) // 戻り値 push後のオブジェクトのlengthpop()
配列から最後の要素を取り除
配列の長さを変化させます開発者モードのConsoleapp.items.pop() // 戻り値 popで取り除いた要素shift()
配列から最初の要素を取り除
配列の長さを変化させます開発者モードのConsoleapp.items.shift() // 戻り値 shiftで取り除いた要素unshift()
配列の最初に1つ以上の要素を追加する
開発者モードのConsoleapp.items.unshift({ message: 'item3' },{ message: 'item4' }) // 戻り値 unshift後のオブジェクトのlengthsort()
配列の要素を in placeでソートします。
開発者モードのConsoleapp.items.sort()reverse()
配列の要素を in placeで反転させます
最初の要素は最後に最後の要素は最初になります開発者モードのConsoleapp.items.reverse()配列の置き換え
変更メソッドは元の配列を変更します
しかし、変更を行わないメソッドもありますfilter()
引数として与えられたテスト関数を書く配列び対して実行し、それに合格した全ての配列要素からなる新しい配列を生成します。
html部分<ul id="example"> <p>filter前</p> <li v-for="item in items" v-bind:key="item.id"> {{ item.message }} </li> <p>filter後</p> <li v-for="item in passed" v-bind:key="item.id"> {{ item.message }} </li> </ul>javascript部分let app = new Vue({ el: '#example', data: { items: [ { message: 'test' }, { message: 'test' } { message: 'tess' } ], passed: [] } })ブラウザ画面filter前 ・test ・test ・tess filter後開発者モードのConsoleapp.passed = app.items.filter( pass => pass.message == 'test' )ブラウザ画面filter前 ・test ・test ・tess filter後 ・test ・testconcat()
配列に他の配列や値を繋いでできた新しい配列を作る
html部分<ul id="example"> <p>concat前</p> <li v-for="item in items" v-bind:key="item.id"> {{ item.message }} </li> <p>concat後</p> <li v-for="item in items3" v-bind:key="item.id"> {{ item.message }} </li> </ul>javascript部分let app = new Vue({ el: '#example', data: { items: [ { message: 'item1' }, { message: 'item2' }, { message: 'item3' } ], items2: [ { message: 'item4' }, { message: 'item5' }, { message: 'item6' } ], items3: [] } })ブラウザ画面concat前 ・item1 ・item2 ・item3 concat後開発者モードのConsoleapp.items3 = app.items.concat(app.items2)ブラウザ画面concat前 ・item1 ・item2 ・item3 concat後 ・item1 ・item2 ・item3 ・item4 ・item5 ・item6slice()
指定された配列の一部をシャローコピーして、新しい配列オブジェクトを返します。
指定するさいに始めの配列番号と終わりの配列番号を指定したら、終わりの配列番号の要素は含まれません。html部分<ul id="example"> <p>slice前</p> <li v-for="(item, index) in items" v-bind:key="item.id"> {{ index }} : {{ item.message }} </li> <p>slice後</p> <li v-for="(item, index) in items2" v-bind:key="item.id"> {{ index }} : {{ item.message }} </li> </ul>javascript部分let app = new Vue({ el: '#example', data: { items: [5 { message: 'item1' }, { message: 'item2' }, { message: 'item3' }, { message: 'item4' } ], items2: [] } })ブラウザ画面slice前 ・0 : item1 ・1 : item2 ・2 : item3 ・3 : item4 slice後開発者モードのConsoleapp.items2 = app.items.slice(1,3)ブラウザ画面slice前 ・0 : item1 ・1 : item2 ・2 : item3 ・3 : item4 slice後 ・0 : item2 ・1 : item3注意事項
javaScriptの制限のため、Vue.jsは配列下記2つの変更を検出することができません。
- インデックスで要素を直接設定するとき。
- 配列の長さを変更するとき
html部分<ul id="example"> <li v-for="item in items"> {{ item }} </li> </ul>javascript部分let app = new Vue({ el: '#example', data: { items: [ 'item1', 'item2' ] } })下記の例はインデックスで要素を直接設定したアンチパターンです。
開発者モードのConsoleapp.items[1] = "item3"自分で実行してみたところ、配列の中にあるオブジェクトのkeyを指定して変更する場合は問題なく実行されました。
下記の例は配列の長さを変更するアンチパターンです。
開発者モードのConsoleapp.items.length = "item3"上記の例に対する解決は存在します。
上記と同じ動作になりますが、リアクティブなシステム内で状況の更新を検出することができます。インスタンスメソッド $set
インデックスで要素を直接設定する時にはインスタンスメソッド $setを使う事で解決できます。
開発者モードのConsoleapp.$set(app.items, 1, 'item3') // app.$set(変更を加える配列, 配列番号, 変更したい値 )vm.splice()
配列の長さを変更するときは変更メソッドのspliceを使います。
開発者モードのConsoleapp.items.splice(app.items.length,0,'item3') // app.items.splice(追加する配列番号,削除する要素の数,追加する要素)オブジェクトの変更検出の注意
javaScriptの制限のため、Vue.jsはプロパティの追加や削除を検出することはできません
html部分<div id="example"> {{ message }} {{ message2 }} </div>javascript部分let app = new Vue({ el: '#example', data: { message: 'オブジェクト' } })開発者モードのConsoleapp.message2 = 'オブジェクト2'Vue.jsは既に作成されたインスタンスに新しいルートイベントのリアクティブプロパティを動的に追加することはできない。しかし、インスタンスメソッド $setを使いネストされたオブジェクトにリアクティブなプロパティを追加することは可能です。
html部分<ul id="example"> <li v-for="value in object"> {{ value }} </li> </ul>javascript部分let app = new Vue({ el: '#example', data: { object: { title: '公式リファレンスをトレスしながら勉強', author: 'Sthudent Camilo', publishedAt: '2019-07-09' } } })開発者モードのConsoleapp.$set(app.object,'message' ,'こんにちわ') // app.$set(変更を加えるオブジェクト, 追加するkey名, 追加する値)Object.assign()
すべての列挙可能なプロパティの値を、1つ以上のコピー元オブジェクトからコピー先オブジェクトにコピーするために使用されます。
html部分<div id="example"> <ul> <p>object1</p> <li v-for="value in object"> {{ value }} </li> <p>object3</p> <li v-for="value in object3"> {{ value }} </li> </ul> </div>javascript部分let app = new Vue({ el: '#example', data: { object: { title: '公式リファレンスをトレスしながら勉強', author: 'Sthudent Camilo', publishedAt: '2019-07-09' }, object2: { subtitle: 'リストレンダリング難しい…', author: '社畜 カミロ', publishedAt: '2019-07-11' }, object3:{} } })ブラウザ画面object1 公式リファレンスをトレスしながら勉強 Sthudent Camilo 2019-07-09 object3開発者モードのConsoleapp.object3 = Object.assign(app.object, app.object2) // app.object3 = Object.assign(コピー先オブジェクト, コピー元オブジェクト)ブラウザ画面object1 公式リファレンスをトレスしながら勉強 社畜 カミロ 2019-07-11 リストレンダリング難しい… object3 公式リファレンスをトレスしながら勉強 社畜 カミロ 2019-07-11 リストレンダリング難しい…コピー先オブジェクトのプロパティは、コピー元に同じ名前のプロパティがあると上書きされます。
コピー先オブジェクトにコピー元オブジェクトが上書きされます。コピー先オブジェクトにコピー元オブジェクトが上書き対策として下記方法があります。
両方のオブジェクトのプロパティを使用して新しいオブジェクト作成する方法です。開発者モードのConsoleapp.object3 = Object.assign({}, app.object, app.object2)ブラウザ画面object1 公式リファレンスをトレスしながら勉強 Sthudent Camilo 2019-07-09 object3 公式リファレンスをトレスしながら勉強 社畜 カミロ 2019-07-11 リストレンダリング難しい…フィルタ/ソートされた結果の表示
元のデータを実際に変更またはリセットすることなしに、フィルタリングやソートされたバージョンの配列を表示したいことがあります。
フィルタリングやソートされた配列を返す算出プロパティを作ることができます。html部分<div id="example"> <ul> <p>配列 フィルタ/ソートされた結果の表示</p> <li v-for="value in evenNumbers"> {{ value }} </li> </ul> </div>javascript部分let app = new Vue({ el: '#example', data: { numbers:[1,2,3,4,5] }, computed: { evenNumbers: function () { return this.numbers.filter(function (number) { return number % 2 === 0 }) } } })算出プロパティが使えない状況ではメソッドを使う事ができる。
html部分<div id="example"> <ul> <p>配列 フィルタ/ソートされた結果の表示</p> <li v-for="value in even(numbers)"> {{ value }} </li> </ul> </div>javascript部分let app = new Vue({ el: '#example', data: { numbers:[1,2,3,4,5] }, methods:{ even: function (numbers) { return numbers.filter(function (number) { return number % 2 === 0 }) } } })範囲付き v-for
v-forは整数値を取ることもできる。
htm部分<div id="example"> <ul> <li v-for="value in 10"> item{{ value }} </li> </ul> </div>上記の例では、指定された数だけ< li >要素が繰り返されます。
コンテンツテンプレートでのv-for
v-if同様に、複数の要素ブロックをレンダリングするために、v-forで < template >タグを使うこともできます。
html部分<ul id="example"> <template v-for="value in object"> <li>{{ value }}</li> </template> </ul>javascript部分let app = new Vue({ el: '#example', data: { object: { title: '公式リファレンスをトレスしながら勉強', author: 'Sthudent Camilo', publishedAt: '2019-07-09' } } })あとがき
v-ifとv-forの題目はv-ifとv-forを同時に利用する事は推奨されておらずバッドプラクティスですということです。
参考資料
javascriptのループについての記事ですが、javascriptのイテレータ構文に近いのでVue.jsのv-forバインディングにも役に立ちます
JavaScriptで配列やオブジェクトをループする良い方法を真剣に検討してみた
- 投稿日:2019-07-11T12:54:38+09:00
Vue.js を勉強する Session7
リストレンダリング
v-forで配列に要素をマッピングする
配列に基づいて、アイテムのリストをレンダリングするために、v-forディレクテイブを使用します。
v-forディレクティブはitem in itemsの形式で特別な構文を要求し、itemsは配列で、itemは配列要素を順不動で復されているエイリアスです。html部分<ul id="example"> <li v-for="item in items"> {{ item.message }} </li> </ul>javascript部分let app = new Vue({ el: '#example', data: { items: [ { message: 'item1' }, { message: 'item2' } ] } })ブラウザ画面・item1 ・item2上記の例ではitems配列の要素をブラウザ画面にレンダリングしています。
v-forブロック内では、親スコープのプロパティへの完全なアクセスを持っています。
またv-forは現在のアイテムに対する配列のインデックスを、2つ目の引数としてサポートしてます。html部分<ul id="example"> <li v-for="(item, index) in items"> [配列番号:{{ index }}] - [配列要素:{{ item.message }}] </li> </ul>ブラウザ画面・[配列番号:0] - [配列要素:item1] ・[配列番号:1] - [配列要素:item2]javascript部分は上記の例と同じです。
indexは配列の要素番号です。また、区切り文字としてinの他にofを使用することができます。
これはjavascriptのイテレータ構文に近いものです。オブジェクトのv-for
オブジェクトのプロパティに対して、v-forを使って反復処理する事ができます。
html部分<ul id="example"> <li v-for="value in object"> {{ value }} </li> </ul>javascript部分let app = new Vue({ el: '#example', data: { object: { title: '公式リファレンスをトレスしながら勉強', author: 'Sthudent Camilo', publishedAt: '2019-07-09' } } })ブラウザ画面・公式リファレンスをトレスしながら勉強 ・Sthudent Camilo ・2019-05-21オブジェクトでは2つ目の引数にプロパティ名(key)もサポートされています。
html部分<ul id="example"> <li v-for="(value, name) in object"> {{ name }} : {{ value }} </li> </ul>ブラウザ画面・title : 公式リファレンスをトレスしながら勉強 ・author : Sthudent Camilo ・publishedAt : 2019-07-09javascriptは上記の例と同じ
オブジェクトはindexもサポートされています。
html部分<ul id="example"> <li v-for="(value, name, index) in object"> {{ index }} . {{ name }} : {{ value }} </li> </ul>ブラウザ画面0 . title : 公式リファレンスをトレスしながら勉強 1 . author : Sthudent Camilo 2 . publishedAt : 2019-07-09【注意】
オブジェクトを反復処理するとき、順序はObject.keys() の列挙順のキーに基いており、全てのjavascriptエンジンの実装で一貫性で保証されていません。
状態の維持
※正直この題目はピンときていので理解が深まり次第追記します。
Vue.jsがv-forで描画された要素のリストを更新する際、標準では”その場でパッチを適応する”方法が用いられます。
データのアイテムの順序が変更された場合、アイテムの順序に合わせてDOM要素を移動する代わりに、Vueは各要素にその場でパッチを適応して、その特定のインデックスに何を描画するべきかを確実に反映します。html部分<ul id="example"> <li v-for="value in object" v-bind:key="value.id"> {{ value }} </li> </ul>繰り返されるDOMの内容が単純な場合や、性能向上のために標準の動作に意図的に頼る場合を除いて、可能なときはいつでもv-forにkey属性を与えることがベストプラクティスです。
詳しく書かれている記事
Vue.js: v-forで項目インデックスをkey属性にしていいのか【注意】
オブジェクトや配列のような非プリミティブ値をv-forのキーとして使わないでください。代わりに、プリミティブ値である文字列や数値を使ってください。
配列の変化を検出
変更メソッド
dataプロパティで宣言した配列に変更を加える配列メソッドは以下の通りです。
html部分<ul id="example"> <li v-for="item in items" v-bind:key="item.id"> {{ item.message }} </li> </ul>javascript部分let app = new Vue({ el: '#example', data: { items: [ { message: 'item1' }, { message: 'item2' } ] } })push()
配列の末尾に要素を追加します
開発者モードのConsoleapp.items.push({ message: 'item3' }) // 戻り値 push後のオブジェクトのlengthpop()
配列から最後の要素を取り除
配列の長さを変化させます開発者モードのConsoleapp.items.pop() // 戻り値 popで取り除いた要素shift()
配列から最初の要素を取り除
配列の長さを変化させます開発者モードのConsoleapp.items.shift() // 戻り値 shiftで取り除いた要素unshift()
配列の最初に1つ以上の要素を追加する
開発者モードのConsoleapp.items.unshift({ message: 'item3' },{ message: 'item4' }) // 戻り値 unshift後のオブジェクトのlengthsort()
配列の要素を in placeでソートします。
開発者モードのConsoleapp.items.sort()reverse()
配列の要素を in placeで反転させます
最初の要素は最後に最後の要素は最初になります開発者モードのConsoleapp.items.reverse()配列の置き換え
変更メソッドは元の配列を変更します
しかし、変更を行わないメソッドもありますfilter()
引数として与えられたテスト関数を書く配列び対して実行し、それに合格した全ての配列要素からなる新しい配列を生成します。
html部分<ul id="example"> <p>filter前</p> <li v-for="item in items" v-bind:key="item.id"> {{ item.message }} </li> <p>filter後</p> <li v-for="item in passed" v-bind:key="item.id"> {{ item.message }} </li> </ul>javascript部分let app = new Vue({ el: '#example', data: { items: [ { message: 'test' }, { message: 'test' } { message: 'tess' } ], passed: [] } })ブラウザ画面filter前 ・test ・test ・tess filter後開発者モードのConsoleapp.passed = app.items.filter( pass => pass.message == 'test' )ブラウザ画面filter前 ・test ・test ・tess filter後 ・test ・testconcat()
配列に他の配列や値を繋いでできた新しい配列を作る
html部分<ul id="example"> <p>concat前</p> <li v-for="item in items" v-bind:key="item.id"> {{ item.message }} </li> <p>concat後</p> <li v-for="item in items3" v-bind:key="item.id"> {{ item.message }} </li> </ul>javascript部分let app = new Vue({ el: '#example', data: { items: [ { message: 'item1' }, { message: 'item2' }, { message: 'item3' } ], items2: [ { message: 'item4' }, { message: 'item5' }, { message: 'item6' } ], items3: [] } })ブラウザ画面concat前 ・item1 ・item2 ・item3 concat後開発者モードのConsoleapp.items3 = app.items.concat(app.items2)ブラウザ画面concat前 ・item1 ・item2 ・item3 concat後 ・item1 ・item2 ・item3 ・item4 ・item5 ・item6slice()
指定された配列の一部をシャローコピーして、新しい配列オブジェクトを返します。
指定するさいに始めの配列番号と終わりの配列番号を指定したら、終わりの配列番号の要素は含まれません。html部分<ul id="example"> <p>slice前</p> <li v-for="(item, index) in items" v-bind:key="item.id"> {{ index }} : {{ item.message }} </li> <p>slice後</p> <li v-for="(item, index) in items2" v-bind:key="item.id"> {{ index }} : {{ item.message }} </li> </ul>javascript部分let app = new Vue({ el: '#example', data: { items: [5 { message: 'item1' }, { message: 'item2' }, { message: 'item3' }, { message: 'item4' } ], items2: [] } })ブラウザ画面slice前 ・0 : item1 ・1 : item2 ・2 : item3 ・3 : item4 slice後開発者モードのConsoleapp.items2 = app.items.slice(1,3)ブラウザ画面slice前 ・0 : item1 ・1 : item2 ・2 : item3 ・3 : item4 slice後 ・0 : item2 ・1 : item3注意事項
javaScriptの制限のため、Vue.jsは配列下記2つの変更を検出することができません。
- インデックスで要素を直接設定するとき。
- 配列の長さを変更するとき
html部分<ul id="example"> <li v-for="item in items"> {{ item }} </li> </ul>javascript部分let app = new Vue({ el: '#example', data: { items: [ 'item1', 'item2' ] } })下記の例はインデックスで要素を直接設定したアンチパターンです。
開発者モードのConsoleapp.items[1] = "item3"自分で実行してみたところ、配列の中にあるオブジェクトのkeyを指定して変更する場合は問題なく実行されました。
下記の例は配列の長さを変更するアンチパターンです。
開発者モードのConsoleapp.items.length = "item3"上記の例に対する解決は存在します。
上記と同じ動作になりますが、リアクティブなシステム内で状況の更新を検出することができます。インスタンスメソッド $set
インデックスで要素を直接設定する時にはインスタンスメソッド $setを使う事で解決できます。
開発者モードのConsoleapp.$set(app.items, 1, 'item3') // app.$set(変更を加える配列, 配列番号, 変更したい値 )vm.splice()
配列の長さを変更するときは変更メソッドのspliceを使います。
開発者モードのConsoleapp.items.splice(app.items.length,0,'item3') // app.items.splice(追加する配列番号,削除する要素の数,追加する要素)オブジェクトの変更検出の注意
javaScriptの制限のため、Vue.jsはプロパティの追加や削除を検出することはできません
html部分<div id="example"> {{ message }} {{ message2 }} </div>javascript部分let app = new Vue({ el: '#example', data: { message: 'オブジェクト' } })開発者モードのConsoleapp.message2 = 'オブジェクト2'Vue.jsは既に作成されたインスタンスに新しいルートイベントのリアクティブプロパティを動的に追加することはできない。しかし、インスタンスメソッド $setを使いネストされたオブジェクトにリアクティブなプロパティを追加することは可能です。
html部分<ul id="example"> <li v-for="value in object"> {{ value }} </li> </ul>javascript部分let app = new Vue({ el: '#example', data: { object: { title: '公式リファレンスをトレスしながら勉強', author: 'Sthudent Camilo', publishedAt: '2019-07-09' } } })開発者モードのConsoleapp.$set(app.object,'message' ,'こんにちわ') // app.$set(変更を加えるオブジェクト, 追加するkey名, 追加する値)Object.assign()
すべての列挙可能なプロパティの値を、1つ以上のコピー元オブジェクトからコピー先オブジェクトにコピーするために使用されます。
html部分<div id="example"> <ul> <p>object1</p> <li v-for="value in object"> {{ value }} </li> <p>object3</p> <li v-for="value in object3"> {{ value }} </li> </ul> </div>javascript部分let app = new Vue({ el: '#example', data: { object: { title: '公式リファレンスをトレスしながら勉強', author: 'Sthudent Camilo', publishedAt: '2019-07-09' }, object2: { subtitle: 'リストレンダリング難しい…', author: '社畜 カミロ', publishedAt: '2019-07-11' }, object3:{} } })ブラウザ画面object1 公式リファレンスをトレスしながら勉強 Sthudent Camilo 2019-07-09 object3開発者モードのConsoleapp.object3 = Object.assign(app.object, app.object2) // app.object3 = Object.assign(コピー先オブジェクト, コピー元オブジェクト)ブラウザ画面object1 公式リファレンスをトレスしながら勉強 社畜 カミロ 2019-07-11 リストレンダリング難しい… object3 公式リファレンスをトレスしながら勉強 社畜 カミロ 2019-07-11 リストレンダリング難しい…コピー先オブジェクトのプロパティは、コピー元に同じ名前のプロパティがあると上書きされます。
コピー先オブジェクトにコピー元オブジェクトが上書きされます。コピー先オブジェクトにコピー元オブジェクトが上書き対策として下記方法があります。
両方のオブジェクトのプロパティを使用して新しいオブジェクト作成する方法です。開発者モードのConsoleapp.object3 = Object.assign({}, app.object, app.object2)ブラウザ画面object1 公式リファレンスをトレスしながら勉強 Sthudent Camilo 2019-07-09 object3 公式リファレンスをトレスしながら勉強 社畜 カミロ 2019-07-11 リストレンダリング難しい…フィルタ/ソートされた結果の表示
元のデータを実際に変更またはリセットすることなしに、フィルタリングやソートされたバージョンの配列を表示したいことがあります。
フィルタリングやソートされた配列を返す算出プロパティを作ることができます。html部分<div id="example"> <ul> <p>配列 フィルタ/ソートされた結果の表示</p> <li v-for="value in evenNumbers"> {{ value }} </li> </ul> </div>javascript部分let app = new Vue({ el: '#example', data: { numbers:[1,2,3,4,5] }, computed: { evenNumbers: function () { return this.numbers.filter(function (number) { return number % 2 === 0 }) } } })算出プロパティが使えない状況ではメソッドを使う事ができる。
html部分<div id="example"> <ul> <p>配列 フィルタ/ソートされた結果の表示</p> <li v-for="value in even(numbers)"> {{ value }} </li> </ul> </div>javascript部分let app = new Vue({ el: '#example', data: { numbers:[1,2,3,4,5] }, methods:{ even: function (numbers) { return numbers.filter(function (number) { return number % 2 === 0 }) } } })範囲付き v-for
v-forは整数値を取ることもできる。
htm部分<div id="example"> <ul> <li v-for="value in 10"> item{{ value }} </li> </ul> </div>上記の例では、指定された数だけ< li >要素が繰り返されます。
コンテンツテンプレートでのv-for
v-if同様に、複数の要素ブロックをレンダリングするために、v-forで < template >タグを使うこともできます。
html部分<ul id="example"> <template v-for="value in object"> <li>{{ value }}</li> </template> </ul>javascript部分let app = new Vue({ el: '#example', data: { object: { title: '公式リファレンスをトレスしながら勉強', author: 'Sthudent Camilo', publishedAt: '2019-07-09' } } })あとがき
v-ifとv-forの題目はv-ifとv-forを同時に利用する事は推奨されておらずバッドプラクティスですということです。
参考資料
javascriptのループについての記事ですが、javascriptのイテレータ構文に近いのでVue.jsのv-forバインディングにも役に立ちます
JavaScriptで配列やオブジェクトをループする良い方法を真剣に検討してみた
- 投稿日:2019-07-11T02:21:44+09:00
Nuxt 2.8の生成するtsconfig.jsonを使うとIntelliJ(WebStorm、PhpStorm等)がCannot find moduleエラーを吐く
※本記事の修正方法は、試行錯誤の結果導き出したもので、Nuxtのビルドシステムの全体的な理解を欠いた不十分なソリューションである可能性があります。ご了承ください
不具合の概要
Nuxt.jsでプロジェクトを作成し、公式の手順でTypeScriptサポートを有効にすると、IntelliJ系のIDEが以下のように「TS2307: Cannot find module」エラーを吐く状態になってしまいます。
※手元の環境はWebStorm 2019.1.3、Nuxt 2.8.1、TypeScript 3.5.3
直し方
*.vue
の型定義をshims-vue.d.ts
という名前で作成し、これをプロジェクトのルートディレクトリに置きます。shims-vue.d.tsdeclare module '*.vue' { import Vue from 'vue' export default Vue }次に、tsconfig.json の設定を調整し、
*.vue
(と、ついでにtsも)をincludeします。tsconfig,.json"files": [ "shims-vue.d.ts" ], "include": [ "components/**/*.ts", "components/**/*.vue", "layouts/**/*.ts", "layouts/**/*.vue", "pages/**/*.ts", "pages/**/*.vue" ], "exclude": [ "node_modules" ]これによって、IDEのエラーが消え、モジュールの解決が動作するようになります。
修正後のプロジェクトは以下のリポジトリに置いてます。
https://github.com/ryo-utsunomiya/nuxt-tsshims-vue.d.ts がなぜ必要かについては以下のissueに詳しいです。
https://github.com/vuejs/vue-cli/issues/1198
簡単にいうと、実際のビルドには不要ですが、IDE(WebStorm/VSCode等)がCannot find moduleエラーを吐かないようにするために必要なファイルです。ちなみに、vue-cliでTypeScriptサポートを有効にした場合はsrc配下に配置されます。Nuxt + TypeScriptプロジェクトの構築手順
本記事で使用したプロジェクトの構築手順を、最後に書いておきます。
npx create-nuxt-app nuxt-ts選択はミニマムで(パッケージマネージャはyarnにしてますがnpmでも問題ないです)。
cd nuxt-ts yarn add -D @nuxt/typescript yarn add ts-node touch tsconfig.json yarn nuxtここまででTypeScriptのセットアップ完了。
次に、.vueファイルの中でTypeScriptを使うため、pages/index.vue のscriptタグに
lang="ts"
を追加。pages/index.vue<script lang="ts">pages/index.vue の中で以下のようなコードを書くと、型チェックエラーが発生します
const add = (a:number, b:number) => a + b; add("a", "b");
- 投稿日:2019-07-11T01:58:53+09:00
vue.jsのディレクティブをまとめてみた。part2
v-for
jsのfor文
index.html<div id="app"> <ul> <li v-for="pref in prefs"><!--変数名 in 配列名--> {{pref.name }} </li> </ul> </div> <script src="https://cdn.jsdelivr.net/npm/vue"></script> <!--vueのCDNを読み込む--> <script> let app=new Vue({ el:"#app", data:{ prefs:[ {name:'北海道'}, {name:'青森県'}, {name:'岩手県'}, {name:'宮城県'}, {name:'秋田県'}, {name:'山形県'}, {name:'福島県'}, ] } }); </script>上記にボタンを押すと、シャッフルできるようにしたい。
lodashというライブラリを使う。index.html<div id="app"> <ul> <li v-for="pref in prefs"><!--変数名 in 配列名--> {{pref.name }} </li> </ul> <button v-on:click="shuffle">シャッフル</button> </div> <script src="https://cdn.jsdelivr.net/npm/vue"></script> <!--vueのCDNを読み込む--> <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.14/lodash.min.js"></script> <script> let app=new Vue({ el:"#app", data:{ prefs:[ {name:'北海道'}, {name:'青森県'}, {name:'岩手県'}, {name:'宮城県'}, {name:'秋田県'}, {name:'山形県'}, {name:'福島県'}, ] }, methods:{ shuffle:function(){ this.prefs=_.shuffle(this.prefs); //_.はlodashを使うためのルール } } }); //ボタンを押すとprefがシャッフルされるという処理になる。 </script>v-on:click
addEventLintener('click',()=>{});に意味が似ている?クリックした後処理をする。
index.html<div id="app"> <p>{{now}}</p> <button v-on:click="time">現在時刻を表示する</button> </div> <script src="https://cdn.jsdelivr.net/npm/vue"></script> <script> let app=new Vue({ el:"#app", data:{ now:"00:00:00" }, methods:{ time:function(e){ var date=new Date(); this.now=date.getHours()+":" +date.getMinutes()+":"+ date.getSeconds(); //現在時刻を表示 } } }); </script>
- 投稿日:2019-07-11T00:23:41+09:00
Vue.js はまったポイントメモ(APIでデータ取得)
Vue.jsを始めて1ヶ月
色んな記事やブログのソースを参考にして、
基本をおろそかにしたらツケが回ってきたので、自戒を込めてメモにします。親子コンポーネントでのデータ受け渡し → pagesでの表示
作りたい形
(親コンポーネント) (子コンポーネント) API叩いてデータ取得(json) → 親からデータを受け取り、templateで整形 ↑ | (pages A) request 'A' 返却 ← (pages B) request 'B' 返却 ← (pages C) request 'C' 返却 ←
- ページ(A~C)にアクセスしたら、親コンポーネントにリクエストを通知
- 親コンポーネントはAxiosでサーバー側APIを叩いてデータを取得
- 取得したデータを子コンポーネントに渡して、templateを適用してviewに返却
下記で紹介されているファクトリパターンAPIを参考にして、小規模アプリを作っています。
【Vue.js】Web API通信のデザインパターン (個人的ベストプラクティス)ハマったポイント 「親comp → 子comp → pagesの流れでpropsすると思った」
index.vue<template> <div id="app"> <p>index.vueの内容です</p> <child-component/> </div> </template> <script> import Child from '../components/Child.vue'; export default { components: { 'child-component': Child, } } </script>pages配下のindex.vueではChildをimportしてきて・・・
Child.vue<template> <p>子コンポーネントの内容です</p> <p>{{ info }}</p> </template> <script> export default { name: 'child', props: ['info'] } </script>ChildはParentからpropsで受け取って・・・
apiComponent.vue<!--親コンポーネント--> <template> <child :info="info" /> </template> <script> import SpotList from './SpotList.vue' import Child from './Child.vue'; import {RepositoryFactory} from '../api/RepositoryFactory' const SpotsRepository = RepositoryFactory.get('spots'); export default { name: "api-component", components: { 'spotlist': SpotList, 'child': Child, }, data() { return { isLoading: false, info: [], //取得したデータはinfoに格納する }; }, created() { this.fetch() }, methods: { async fetch() { this.isLoading = true; const {data} = await SpotsRepository.get(); // データ取得 this.isLoading = false; this.info = data; } } } </script>親はAPIから取得したデータを配列に入れて、
v-bind
すれば・・・
なにも表示されない(悲)結論としてはpages側のImportを親コンポーネントに変えると表示されました。
index.vue<template> <div id="app"> <api-component /> </div> </template> <script> import ApiComponent from '../components/apiComponent.vue'; export default { components: { 'api-component': ApiComponent, } } </script>キャメルケース、ケバブケースなど記載の仕方が違う?
データ反映をmounted
にする?など、色々試したのですが上手く行かず、時間を費やしました。
v-bind
などが絡む場所は、コンポーネント間の関係に気をつけないといけませんね。。。