20190711のvue.jsに関する記事は12件です。

初心者向け!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 yarn

windowsの方はこちらから
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を入力してみましょう。
localhost_8080_.png
この画面が表示されたら無事、環境構築が終了しています。
お疲れさまでした。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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のページでアカウント作成

[Google Analytics]

2.vue-analyticsのインストール・設定

vue-analyticsのgithub

インストール

npm install vue-analytics -save

設定

main.jsに追記

main.js
import VueAnalytics from 'vue-analytics'

Vue.use(VueAnalytics, {
  id: 'UA-XXX-X'      google analyticsID
})

ES5の書き方の場合はmain.jsは以下のようにする。

main.js
const VueAnalytics = require('vue-analytics').default

Vue.use(VueAnalytics, {
  id: 'UA-XXX-X'      google analyticsID
})

以上でGoogle Analyticsのページに反映されます。
キャプチャ.JPG

その他

上記でも使っているVue.use()ってそもそも何なのかという初歩的なことがあいまいだったのでメモ。
・Vur.use()はプラグインを使用するために使用する。
・プラグインとはVueにグローバル・メソッドやグローバル・アセット、コンポーネントアクションなどを追加するもの。

参考:
Vue.use( )を書く場合と書かない場合
公式ガイド-プラグイン

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

とあるVue Routingのインデックス

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Vue.js用のVSCode設定

Vue.js用のVSCodeの設定はVueMasteryこの動画がおすすめ。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Vue.jsでログイン画面作り続けないと発作が出るお話(環境構築編)

2019-07-10-miyaji-vue-create-login_test-000.jpg

「...うぅ...つ...作りたい...作りたいぃ...」

2019-07-10-miyaji-vue-create-login_test-001.jpg

ログイン画面を...作りたいィィィィィィィィィ!!!!!

2019-07-10-miyaji-vue-create-login_test-002.jpg

すいません。唐突にログイン画面を作らないと発症する発作が出てしまいました。みやゆーです。

発作を収めるために早速ログイン画面を作っていきたいと思います。

どうやって発作を抑えるか

とはいえ、どのようにログイン画面を作っていくかが問題です。

今回の発作は急に発症し、症状も激しいので一刻の猶予もありません。

ここはサクッとページを作成していけるVue.jsと,導入やユーザー管理も簡単なFirebaseを使って作っていきましょう。

なぜVue.jsとFirebaseを使うのかは、それを説明しないと発症する発作が出れば説明します。強いて言えば「少しだけ知見があるから」。そんなもんです。

できるかな?じゃない、やるんだよ

早速やっていきましょう。まずは環境構築です。

環境構築

$ node -v
v10.15.3

$vue -V
3.7.0

$ npm -v
6.4.1

Vue-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

ほーん。defaultManually select featuresを選べってか。

defaultにはbabeleslintしか入ってないのね。

他にもいっぱいぶち込みたいので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.json

Babelとか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-10-miyaji-vue-create-login_test-003.png

できた!あとはログイン画面を作るだけや!

2019-07-10-miyaji-vue-create-login_test-004.jpg

まだまだ長いやんけ...

でも発作は収まったので良しとします。

また発症したら続きを描きます。みやゆーでした。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【ヘルパー関数】ストアとコンポーネント間の通信

参考文献
Vue.js入門

Vueインスタンスにstoreを渡してあるものとします。

ヘルパー関数

ヘルパー関数とは、コンポーネントからストアにアクセスする為の関数で下記の4つが用意されています。

・mapState
・mapMutations
・mapGetters
・mapActions

これを使い、コンポーネントの算出プロパティやメソッドに結び付けられます。

比較のためにthis.storeを使った参照の例を書きます。

this.storeを使って参照

store.js
import 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.js
import { mapState } from 'vuex'

export default {
  // '$sotre.state.count'をthis.valueと結びつける
  computed: mapState({
    value: 'count'
  })
}

ヘルパー関数は簡単にコンポーネントからストアを使うことができますが、これでは通常の算出プロパティやメソッドを書く場所がなくなります。
そのような場合、ヘルパー関数の戻り値と通常のこれでは通常の算出プロパティ・メソッドの定義を、オブジェクトスプレッド演算子やobject.assign関数で結合し、両方一度に使うことができます。

下記はmapStateでstateのcountを結びながら通常の算出プロパティdoubleを定義しています。

App.vue
import { mapState } from 'vuex'

export default {
  // 通常の算出プロパティを定義
  computed: {
    double: function() {
      return this.conut * 2
    },
    // 通常の算出プロパティとmapStateの戻り値を結合
    ...mapState([
      'count'
    ])
  }
}

名前空間つきのモジュールは、ヘルパー関数の第一引数に名前空間の文字列を渡すことにより記述できます。
下記は、counter名前空間にあるcountをthis.countに結ぶ例です。

App.vue
import { mapState } from 'vuex'

export default {
  // '$store.state.counter.count'を'this.count'に結ぶ
  computed: mapState('counter',[
    'count'
  ])
}

以上です。
また学習が進み次第、更新、掲載していきます。
ここまでで補足や訂正などありましたらご教授いただけると嬉しいです。
最後まで読んでいただきありがとうございます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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-09

javascriptは上記の例と同じ

オブジェクトは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-forkey属性を与えることがベストプラクティスです。

詳しく書かれている記事
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()

配列の末尾に要素を追加します

開発者モードのConsole
app.items.push({ message: 'item3' })
// 戻り値 push後のオブジェクトのlength

pop()

配列から最後の要素を取り除
配列の長さを変化させます

開発者モードのConsole
app.items.pop()
// 戻り値 popで取り除いた要素

shift()

配列から最初の要素を取り除
配列の長さを変化させます

開発者モードのConsole
app.items.shift()
// 戻り値 shiftで取り除いた要素

unshift()

配列の最初に1つ以上の要素を追加する

開発者モードのConsole
app.items.unshift({ message: 'item3' },{ message: 'item4' })
// 戻り値 unshift後のオブジェクトのlength

sort()

配列の要素を in placeでソートします。

開発者モードのConsole
app.items.sort()

reverse()

配列の要素を in placeで反転させます
最初の要素は最後に最後の要素は最初になります

開発者モードのConsole
app.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後
開発者モードのConsole
app.passed = app.items.filter(
  pass => pass.message == 'test'
)
ブラウザ画面
filter前
・test
・test
・tess
filter後
・test
・test

concat()

配列に他の配列や値を繋いでできた新しい配列を作る

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後

開発者モードのConsole
app.items3 = app.items.concat(app.items2)
ブラウザ画面
concat前
・item1
・item2
・item3
concat後
・item1
・item2
・item3
・item4
・item5
・item6

slice()

指定された配列の一部をシャローコピーして、新しい配列オブジェクトを返します。
指定するさいに始めの配列番号と終わりの配列番号を指定したら、終わりの配列番号の要素は含まれません。

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後

開発者モードのConsole
app.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'
    ]
  }
})

下記の例はインデックスで要素を直接設定したアンチパターンです。

開発者モードのConsole
app.items[1] = "item3"

自分で実行してみたところ、配列の中にあるオブジェクトのkeyを指定して変更する場合は問題なく実行されました。

下記の例は配列の長さを変更するアンチパターンです。

開発者モードのConsole
app.items.length = "item3"

上記の例に対する解決は存在します。
上記と同じ動作になりますが、リアクティブなシステム内で状況の更新を検出することができます。

インスタンスメソッド $set

インデックスで要素を直接設定する時にはインスタンスメソッド $setを使う事で解決できます。

開発者モードのConsole
app.$set(app.items, 1, 'item3')
// app.$set(変更を加える配列, 配列番号, 変更したい値 )

vm.splice()

配列の長さを変更するときは変更メソッドのspliceを使います。

開発者モードのConsole
app.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: 'オブジェクト'
  }
})
開発者モードのConsole
app.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'
    }
  }
})
開発者モードのConsole
app.$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
開発者モードのConsole
app.object3 = Object.assign(app.object, app.object2)
// app.object3 = Object.assign(コピー先オブジェクト, コピー元オブジェクト)
ブラウザ画面
object1

公式リファレンスをトレスしながら勉強
社畜 カミロ
2019-07-11
リストレンダリング難しい…

object3

公式リファレンスをトレスしながら勉強
社畜 カミロ
2019-07-11
リストレンダリング難しい…

コピー先オブジェクトのプロパティは、コピー元に同じ名前のプロパティがあると上書きされます。
コピー先オブジェクトにコピー元オブジェクトが上書きされます。

コピー先オブジェクトにコピー元オブジェクトが上書き対策として下記方法があります。
両方のオブジェクトのプロパティを使用して新しいオブジェクト作成する方法です。

開発者モードのConsole
app.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で配列やオブジェクトをループする良い方法を真剣に検討してみた

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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-09

javascriptは上記の例と同じ

オブジェクトは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-forkey属性を与えることがベストプラクティスです。

詳しく書かれている記事
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()

配列の末尾に要素を追加します

開発者モードのConsole
app.items.push({ message: 'item3' })
// 戻り値 push後のオブジェクトのlength

pop()

配列から最後の要素を取り除
配列の長さを変化させます

開発者モードのConsole
app.items.pop()
// 戻り値 popで取り除いた要素

shift()

配列から最初の要素を取り除
配列の長さを変化させます

開発者モードのConsole
app.items.shift()
// 戻り値 shiftで取り除いた要素

unshift()

配列の最初に1つ以上の要素を追加する

開発者モードのConsole
app.items.unshift({ message: 'item3' },{ message: 'item4' })
// 戻り値 unshift後のオブジェクトのlength

sort()

配列の要素を in placeでソートします。

開発者モードのConsole
app.items.sort()

reverse()

配列の要素を in placeで反転させます
最初の要素は最後に最後の要素は最初になります

開発者モードのConsole
app.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後
開発者モードのConsole
app.passed = app.items.filter(
  pass => pass.message == 'test'
)
ブラウザ画面
filter前
・test
・test
・tess
filter後
・test
・test

concat()

配列に他の配列や値を繋いでできた新しい配列を作る

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後

開発者モードのConsole
app.items3 = app.items.concat(app.items2)
ブラウザ画面
concat前
・item1
・item2
・item3
concat後
・item1
・item2
・item3
・item4
・item5
・item6

slice()

指定された配列の一部をシャローコピーして、新しい配列オブジェクトを返します。
指定するさいに始めの配列番号と終わりの配列番号を指定したら、終わりの配列番号の要素は含まれません。

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後

開発者モードのConsole
app.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'
    ]
  }
})

下記の例はインデックスで要素を直接設定したアンチパターンです。

開発者モードのConsole
app.items[1] = "item3"

自分で実行してみたところ、配列の中にあるオブジェクトのkeyを指定して変更する場合は問題なく実行されました。

下記の例は配列の長さを変更するアンチパターンです。

開発者モードのConsole
app.items.length = "item3"

上記の例に対する解決は存在します。
上記と同じ動作になりますが、リアクティブなシステム内で状況の更新を検出することができます。

インスタンスメソッド $set

インデックスで要素を直接設定する時にはインスタンスメソッド $setを使う事で解決できます。

開発者モードのConsole
app.$set(app.items, 1, 'item3')
// app.$set(変更を加える配列, 配列番号, 変更したい値 )

vm.splice()

配列の長さを変更するときは変更メソッドのspliceを使います。

開発者モードのConsole
app.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: 'オブジェクト'
  }
})
開発者モードのConsole
app.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'
    }
  }
})
開発者モードのConsole
app.$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
開発者モードのConsole
app.object3 = Object.assign(app.object, app.object2)
// app.object3 = Object.assign(コピー先オブジェクト, コピー元オブジェクト)
ブラウザ画面
object1

公式リファレンスをトレスしながら勉強
社畜 カミロ
2019-07-11
リストレンダリング難しい…

object3

公式リファレンスをトレスしながら勉強
社畜 カミロ
2019-07-11
リストレンダリング難しい…

コピー先オブジェクトのプロパティは、コピー元に同じ名前のプロパティがあると上書きされます。
コピー先オブジェクトにコピー元オブジェクトが上書きされます。

コピー先オブジェクトにコピー元オブジェクトが上書き対策として下記方法があります。
両方のオブジェクトのプロパティを使用して新しいオブジェクト作成する方法です。

開発者モードのConsole
app.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で配列やオブジェクトをループする良い方法を真剣に検討してみた

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Nuxt 2.8の生成するtsconfig.jsonを使うとIntelliJ(WebStorm、PhpStorm等)がCannot find moduleエラーを吐く

※本記事の修正方法は、試行錯誤の結果導き出したもので、Nuxtのビルドシステムの全体的な理解を欠いた不十分なソリューションである可能性があります。ご了承ください :pray:

不具合の概要

Nuxt.jsでプロジェクトを作成し、公式の手順でTypeScriptサポートを有効にすると、IntelliJ系のIDEが以下のように「TS2307: Cannot find module」エラーを吐く状態になってしまいます。

Screen Shot 2019-07-11 at 0.51.53.png

※手元の環境はWebStorm 2019.1.3、Nuxt 2.8.1、TypeScript 3.5.3

直し方

*.vue の型定義を shims-vue.d.ts という名前で作成し、これをプロジェクトのルートディレクトリに置きます。

shims-vue.d.ts
declare 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のエラーが消え、モジュールの解決が動作するようになります。

Screen Shot 2019-07-11 at 2.25.41.png

修正後のプロジェクトは以下のリポジトリに置いてます。
https://github.com/ryo-utsunomiya/nuxt-ts

shims-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でも問題ないです)。

Screen Shot 2019-07-11 at 0.45.42.png

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 の中で以下のようなコードを書くと、型チェックエラーが発生します :thumbsup:

const add = (a:number, b:number) => a + b;
add("a", "b");

Screen Shot 2019-07-11 at 2.09.42.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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>

part1
vue.jsのディレクティブをまとめてみました。part1

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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すれば・・・
スクリーンショット 2019-07-10 23.51.43.png
なにも表示されない(悲)

結論としては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>

スクリーンショット 2019-07-10 23.56.22.png

キャメルケース、ケバブケースなど記載の仕方が違う?
データ反映をmountedにする?など、色々試したのですが上手く行かず、時間を費やしました。

v-bindなどが絡む場所は、コンポーネント間の関係に気をつけないといけませんね。。。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む