20191008のvue.jsに関する記事は10件です。

10分でわからるVue.js-超入門

はじめに

皆さん、こんにちは!Webシステム開発エンジニアの蘭です!
今日はVue.jsについて語りたいと思います。

昔Webシステム開発技術が始まった時、バックエンドではPHPやRubyを使い直接OracleやMySQLの内部のデータベースにSELECT,INSERT,UPDATE,DELETEを実行してた時代でした。

それが今はSaasの時代になり、内部データを直接弄るだけではなく、
フロントバックエンドの合化、外部連携の柔軟性が整ってる便利なREST APIファースト開発が主になり、フロントで「サイト更新の速度」や直感的なリ「アルタイムの更新」がサイト品質に関してもはや欠かせない物になりました。
 参考:APIファーストで開発する7つのメリット

やりたいこと:【サイト更新速度の向上、直感的なアルタイムの更新】

バックエンドではサーバーに対するリクエストはAPIでプロパティを渡し、
フロントではJavascriptを使い、最小限の範囲で非同期にVirtual DOMを更新する事が現在APIファーストの開発では重要な事です。

 参考:
   JavaScript初心者でもすぐわかる!DOMとは何か?
   VirtualDOMの仕事ってなに?表示速度がはやい理由

何故Vue.js

理由は比較的に簡単

・Javascriptがあまり分からない初心者でも学べるJavascriptフレームワーク
・単一ファイルコンポーネントで、HTML、CSS、Javascriptが同一のファイルで管理できる。
alt

もちろん、自分に合ったJavascriptフレームを選択するのが一番ですね。  
参考:
   JavaScript: フレームワーク React/Vue/Angularについて
   Vue・React・Angularのパフォーマンス比較検証

始めよう!Vue.js

Vue.jsって何?

・Webアプリケーションでユーザーインターフェースを構築するため、オープンソースのJavascriptフレームワーク。
・Axios等他のJavascriptライブラリが導入できる。
・高機能なシングルページアプリケーション(SPA)を構築することができる。
・vue-routerやvue-validation,vuex等組み合わせることで、大規模なWebアプリ開発のニーズまでサポートする統合的な環境を提供し、作者Evan氏の「Progressive Framework」の概念を活かす。
・ECMAScript 5をベースに、現在のブラウザーではほぼ使える。
参考:
   作者Evan氏のVue.js Progressive Framework
   ECMAScript 5
   ES5とES6の違いをまとめてみた

Vue.jsのインストール

こちらについては以下の公式記事を参考してください。
   Vue.jsのインストール

実際の開発ではnpmでインストールしますが、練習用はCDNでもできます。

Vue.js_cdn
 <script src="https://cdn.jsdelivr.net/npm/vue@2.6.0"> 
 </script>

ドキュメント

Vue.jsは日本語版で、内容は充実。
 Vue.jsの公式マニュアル

1.Hello World

【以下のコードはこちらの記事を引用してます。】


See the Pen
Vue_Hello World
by Uramaya (@uramaya)
on CodePen.


2.テンプレート

v-if / v-else-if / v-else

See the Pen Vue_Template by Uramaya (@uramaya) on CodePen.

See the Pen Vue_Template_V-if_2 by Uramaya (@uramaya) on CodePen.

v-show

See the Pen Vue_Template_V-Show by Uramaya (@uramaya) on CodePen.

繰り返し:v-for

See the Pen Vue_Template_V-for by Uramaya (@uramaya) on CodePen.

3.クラスとスタイル

HTMLクラス

See the Pen Vue_Template_V-HTMLClass by Uramaya (@uramaya) on CodePen.

style属性

See the Pen Vue_Template_V-Style by Uramaya (@uramaya) on CodePen.

4.フォーム入力

テキストボックス、エリアに文字入力

See the Pen Vue_Template_V-From-text by Uramaya (@uramaya) on CodePen.

セレクトボックス

See the Pen Vue_Template_V-SelectBox by Uramaya (@uramaya) on CodePen.

チェックボックス

See the Pen Vue_Template_V-From-checkbox by Uramaya (@uramaya) on CodePen.

ラジオ

See the Pen Vue_Template_V-From-radio by Uramaya (@uramaya) on CodePen.

ファイル

See the Pen Vue_Template_V-From-file by Uramaya (@uramaya) on CodePen.

その他

See the Pen ExxaOXz by Uramaya (@uramaya) on CodePen.

5.イベントとmethods

タブ -click

See the Pen Vue_Template_V-Click by Uramaya (@uramaya) on CodePen.

フォーム -submit

See the Pen Vue_Template_V-submit by Uramaya (@uramaya) on CodePen.

ファイルプレビュー -change

See the Pen Vue_Template_V-Change by Uramaya (@uramaya) on CodePen.

6.算出プロパティ

computed に定義した関数は、関数内部で参照しているプロパティが更新された時に自動的に呼ばれます。こちらではbirthday プロパティの値に変更があるたびに呼ばれています。

See the Pen Vue Computed by Masahiro Harada (@MasahiroHarada) on CodePen.

See the Pen Vue_Template_V-Calculate by Uramaya (@uramaya) on CodePen.

5.ウォッチャ

機能としてはcomputed と変わりません。

See the Pen Jjjoevo by Uramaya (@uramaya) on CodePen.

まとめ

いかがでしょうか。
今回はVue.jsについての簡単な紹介をしました。
こちら説明を入れる時間がなくてすみません。
Vue.jsが好きなっていただければ、嬉しいです。:D
(ちょっと現場の仕事で時間が足りなく、土日も...また説明を加えます。)

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

10分で基礎がわからるVue.js-入門

はじめに

皆さん、こんにちは!Webシステム開発エンジニアの蘭です!
今日はVue.jsについて語りたいと思います。

昔Webシステム開発技術が始まった時、バックエンドではPHPやRubyを使い直接OracleやMySQLの内部のデータベースにSELECT,INSERT,UPDATE,DELETEを実行してた時代でした。

それが今はSaasの時代になり、内部データを直接弄るだけではなく、
フロントバックエンドの合化、外部連携の柔軟性が整ってる便利なREST APIファースト開発が主になり、フロントで「サイト更新の速度」や直感的なリ「アルタイムの更新」がサイト品質に関してもはや欠かせない物になりました。
 参考:APIファーストで開発する7つのメリット

やりたいこと:【サイト更新速度の向上、直感的なアルタイムの更新】

バックエンドではサーバーに対するリクエストはAPIでプロパティを渡し、
フロントではJavascriptを使い、最小限の範囲で非同期にVirtual DOMを更新する事が現在APIファーストの開発では重要な事です。

 参考:
   JavaScript初心者でもすぐわかる!DOMとは何か?
   VirtualDOMの仕事ってなに?表示速度がはやい理由

何故Vue.js

理由は比較的に簡単

・Javascriptがあまり分からない初心者でも学べるJavascriptフレームワーク
・単一ファイルコンポーネントで、HTML、CSS、Javascriptが同一のファイルで管理できる。
alt

もちろん、自分に合ったJavascriptフレームを選択するのが一番ですね。  
参考:
   JavaScript: フレームワーク React/Vue/Angularについて
   Vue・React・Angularのパフォーマンス比較検証

始めよう!Vue.js

Vue.jsって何?

・Webアプリケーションでユーザーインターフェースを構築するため、オープンソースのJavascriptフレームワーク。
・Axios等他のJavascriptライブラリが導入できる。
・高機能なシングルページアプリケーション(SPA)を構築することができる。
・vue-routerやvue-validation,vuex等組み合わせることで、大規模なWebアプリ開発のニーズまでサポートする統合的な環境を提供し、作者Evan氏の「Progressive Framework」の概念を活かす。
・ECMAScript 5をベースに、現在のブラウザーではほぼ使える。
  ※ES6で書くと、動かない場合があります。(特にIE)
参考:
   作者Evan氏のVue.js Progressive Framework
   ECMAScript 5
   ES5とES6の違いをまとめてみた

Vue.jsのインストール

こちらについては以下の公式記事を参考してください。
   Vue.jsのインストール

実際の開発ではnpmでインストールしますが、練習用はCDNでもできます。

Vue.js_cdn
 <script src="https://cdn.jsdelivr.net/npm/vue@2.6.0"> 
 </script>

ドキュメント

Vue.jsは日本語版で、内容は充実。
 Vue.jsの公式マニュアル

1.Hello World

【以下のコードはこちらの記事を引用してます。】


See the Pen
Vue_Hello World
by Uramaya (@uramaya)
on CodePen.


2.テンプレート

v-if / v-else-if / v-else

See the Pen Vue_Template by Uramaya (@uramaya) on CodePen.

See the Pen Vue_Template_V-if_2 by Uramaya (@uramaya) on CodePen.

v-show

See the Pen Vue_Template_V-Show by Uramaya (@uramaya) on CodePen.

繰り返し:v-for

See the Pen Vue_Template_V-for by Uramaya (@uramaya) on CodePen.

3.クラスとスタイル

HTMLクラス

See the Pen Vue_Template_V-HTMLClass by Uramaya (@uramaya) on CodePen.

style属性

See the Pen Vue_Template_V-Style by Uramaya (@uramaya) on CodePen.

4.フォーム入力

テキストボックス、エリアに文字入力

See the Pen Vue_Template_V-From-text by Uramaya (@uramaya) on CodePen.

セレクトボックス

See the Pen Vue_Template_V-SelectBox by Uramaya (@uramaya) on CodePen.

チェックボックス

See the Pen Vue_Template_V-From-checkbox by Uramaya (@uramaya) on CodePen.

ラジオ

See the Pen Vue_Template_V-From-radio by Uramaya (@uramaya) on CodePen.

ファイル

See the Pen Vue_Template_V-From-file by Uramaya (@uramaya) on CodePen.

その他

See the Pen ExxaOXz by Uramaya (@uramaya) on CodePen.

5.イベントとmethods

タブ -click

See the Pen Vue_Template_V-Click by Uramaya (@uramaya) on CodePen.

フォーム -submit

See the Pen Vue_Template_V-submit by Uramaya (@uramaya) on CodePen.

ファイルプレビュー -change

See the Pen Vue_Template_V-Change by Uramaya (@uramaya) on CodePen.

6.算出プロパティ

computed に定義した関数は、関数内部で参照しているプロパティが更新された時に自動的に呼ばれます。こちらではbirthday プロパティの値に変更があるたびに呼ばれています。

See the Pen Vue Computed by Masahiro Harada (@MasahiroHarada) on CodePen.

See the Pen Vue_Template_V-Calculate by Uramaya (@uramaya) on CodePen.

7.ウォッチャ

機能としてはcomputed と変わりません。

See the Pen Jjjoevo by Uramaya (@uramaya) on CodePen.

8.コンポーネント

内容は以下を引用
  Vue.jsでSPAへの移行-コンポーネントを使ってみよう
  Vue.js「コンポーネント」入門

コンポーネントとは簡単に説明すると、UI(ユーザーインターフェース)を作成する要素がまとまったものです。HTML、データ、ロジック、CSSを要素としてコンポーネントに含むことができます。そのコンポーネントを組み合わせることで、Webアプリケーションを作成することができます。作成したコンポーネントには名前が付けられます。その名前を登録し呼び出すことで、必要な時に何度でもアプリケーション内で使用することができます。

以下の利点があります。

・再利用が可能:
作成したコンポーネントは、必要なだけ何度でも再利用することができます。例えば、入力フォームのコンポーネントを作成すれば、そのフォームが必要なページにコンポーネントを登録し、HTML内にタグを追加することでフォームが追加されます。同じ構造や機能を開発し直すコストを軽減することができ、開発効率向上。
・コンポーネント単位で開発を行うことが可能:
コンポーネントごとに構造や機能が振り分けられているため、コンポーネント単位で複数人での開発を並行して進めることが可能です。また、Webアプリケーション内で何か問題が発生した際に、コンポーネント単位で切り分けて問題を対処することができます。

alt
alt

コンポーネントの構造

基本的にこのvueファイル一つで一つのコンポーネントを構成します。

vueファイルは主に
・templateタグ:コンポーネントのhtml要素を埋め込む
・scriptタグ:javascriptを記載する
・styleタグ:cssを記載する

xx.vue
<template>
<!-- ここにhtmlを記載します -->
</template>


<script>
// ここにjavascriptを記載します
</script>


<style>
/* ここにcssを記載します */
</style>

コンポーネントを作成してみよう

Header.vue
Header.vue
<template>
    <div>
        <h1>{{ title }}</h1>
        <p>{{ text }}</p>
    </div>
</template>

<script>
export default {
    data(){
        return {
            title: "Header",
            text: "Hello Vue.js!"
        }
    }
}
</script>

<style scoped>
div{
    border: 1px solid blue
}
h1{
    color: blue
}
p{
    color:blue
}
</style>
Body.vue
Body.vue
<template>
    <div>
        <h2>{{ title }}</h2>
        <p>{{ text }}</p>
    </div>
</template>

<script>
export default {
    data(){
        return {
            title: "Body",
            text: "Have a good day!"
        }
    }
}
</script>

<style scoped>
div{
    border: 1px solid red
}
h2{
    color: red
}
p{
    color: red
}
</style>
App.vue

先ほど作成したHeader.vueとBody.vueをApp.vueからまとめて呼び出します。

App.vue
<template>
  <div>
    <Header></Header>
    <Body></Body>
    <Body></Body>
  </div>
</template>

<script>
import Header from './Header.vue'
import Body from './Body.vue'

export default {
  components: {
    Header,
    Body
  }
}
</script>
イメージとしては以下になります。

alt

コンポーネント間のデータ受け渡し

1.親→子

【親→子】親側のデータ渡し口(タグ属性)
App.vue
<template>
  <div>
  //★【親→子】親側のデータ渡し口(タグ属性)
    <Header :username='name'></Header>
    〜略〜
  </div>
</template>

<script>
〜略〜

export default {
  data(){
    return {
      name: "kiyokiyo"
    }
  },
  〜略〜
}
</script>
【親→子】子側のデータ受け取り口(props)

 子コンポーネント側ではpropsを使ってデータを受け取ります。

Header.vue
<template>
    <div>
        〜略〜
        <p>Welcome! {{ username }}!</p>
    </div>
</template>

<script>
export default {
  //★子コンポーネント側ではpropsを使ってデータを受け取ります。
    props: {
        username: String
    },
    〜略〜
}
</script>
イメージとしては以下になります。

alt

2.子→親

App.vue
<template>
  <div>
    <Header :username='name'></Header>
    //★親側のデータ受け取り口(イベントと関数引数)
    <Body @add="add1"></Body>
    <Body @add="add2"></Body>
    <p>total : {{ totalcount }} </p>
  </div>
</template>

<script>
import Header from './Header.vue'
import Body from './Body.vue'

export default {
  data(){
    return {
      name: "kiyokiyo",
      count1: 0,
      count2: 0,
      totalcount: 0
    }
  },
  components: {
    Header,
    Body
  },
  methods:{
    add1(count){
      this.count1 = count;
      this.totalcount = this.count1 + this.count2;
    },
    add2(count){
      this.count2 = count;
      this.totalcount = this.count1 + this.count2;
    }
  }

}
</script>
Body.vue
<template>
    <div>
        <h2>{{ title }}</h2>
        <p>{{ text }}</p>
        <p><button @click="increment">+1</button> {{ count }} </p>
    </div>
</template>

<script>
export default {
    data(){
        return {
            title: "Body",
            text: "Have a good day!",
            count: 0
        }
    },
    methods: {
        increment(){
            this.count += 1;
            //★子側のデータ渡し口($emit)
            this.$emit("add",this.count);
        }
    }
}
</script>
イメージとしては以下になります。

alt

8.VueでREST API通信

VueでAPI通信はAPIでJsonデータを取得する際に使われます。
こちらに関しては以下の記事を見てくださいね。

 10分でわかる:Vue.jsとaxios を利用した API の使用-初心者向け

9.Vueのライフサイクルフックについて

Vueインスタンスが作成の際に、フックが実行されるタイミングがわかり、メソッドを実行する時どのフックを使えばいいか理解できます。

ライフサイクルダイアグラム

・以下の記事を参考してください。
  Vueのライフサイクルについて
  ライフサイクルダイアグラム

まとめ

いかがでしょうか。
今回はVue.jsについての簡単な紹介をしました。
こちら説明を入れる時間がなくてすみません。
Vue.jsが好きなっていただければ、嬉しいです。:D
(ちょっと現場の仕事で時間が足りなく、土日も...また説明を加えます。)

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

Nuxt.jsで未利用のVueコンポーネントを探すシェルスクリプト

最近Nuxt.jsでWebアプリを作ってるけど、
度重なる改修でVueコンポーネントが乱立。。

使ってないのもたくさんありそうなので、調べるスクリプトを作ってみた。

スクリプトはこんな感じ

#!/bin/bash

# vueコンポーネントの一覧を取得
FILES=`find components -name "*.vue"`
for i in $FILES; do
  #  全体からコンポーネントをインクルードしている行の数を取得
  NUM=`grep -r "$i" * | wc -l | sed -e "s:[^0-9]*::g"`

  # ファイル名と見つけた件数を表示
  echo "** ${NUM}: ${i}"

  # grepした結果を表示(確認用)
  grep -r "$i" * 
  echo ""
done

こんな感じで出力されるので、** 0:で始まるコンポーネントを削除していけばOK。

** 1: components/Hero.vue
pages/index.vue:import Hero from "~/components/Hero.vue";

** 0: components/OgpUserStock.vue

** 0: components/Card.vue

** 3: components/atom/TotalNumBooks.vue
pages/clip/_uid.vue:import TotalNumBooks from "~/components/atom/TotalNumBooks.vue";
pages/read/_uid.vue:import TotalNumBooks from "~/components/atom/TotalNumBooks.vue";
pages/stack/_uid.vue:import TotalNumBooks from "~/components/atom/TotalNumBooks.vue";

確認用にgrepの結果を出しているけど、コメントアウトしたり、

NUMが0件のときは、結果を表示しないようにすればいい感じ。

もしくは、| grep "** 0:"で結果をgrepするとかでもいいかも。

appとかディレクトリを変えてる場合

こんな感じにapp配下とかに場所を変えている場合は、

app/
  pages/
  components/

こんな感じで、findする場所を変えればOK♪

#!/bin/bash

FILES=`find app/components -name "*.vue" | sed 's:app/::g'`
for i in $FILES; do
  NUM=`grep -r "$i" app/* | wc -l | sed -e "s:[^0-9]*::g"`
  echo "** ${NUM}: ${i}"
  grep -r "$i" app/* 
  echo ""
done

以上!!

こんなのつくってます!!

積読用の読書管理アプリ 『積読ハウマッチ』をリリースしました!
積読ハウマッチは、Nuxt.js+Firebaseで開発してます!

もしよかったら、遊んでみてくださいヽ(=´▽`=)ノ

要望・感想・アドバイスなどあれば、
公式アカウント(@MemoryLoverz)や開発者(@kira_puka)まで♪

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

Vue.js: Vue I18nの公式ドキュメントに見当たらず悩んだふたつのこと

Vue I18nは、Vueアプリケーションを国際化(多言語対応)させるためのプラグインです。ページに表示するテキストを、ロケールに応じて切り替えられます。インストールから基本的な設定と使い方までは「Vue.js: Vue I18nでアプリケーションを多言語に対応させる」でご説明しました。本稿では、公式ドキュメントに解説が見当たらず悩んだことをふたつ紹介します。

01 プレースホルダーを多言語化する

実は、プレイスホルダーを使うことは推奨されないようです。そうはいっても、入力例を示すなど、使う場面は少なくないでしょう。ところが、つぎのように記述すると、式($t('placeholder'))がそのまま表示されてしまい、翻訳テキストが取り出せませんでした。

<input type="text"
    placeholder="$t('placeholder')">

Vue I18nサイトのドキュメントには見当たらず、英語でも情報は多くありません。Stack Overflowで見つけたのが、v-bind(省略記法:)を加えなければならないということです。たったひと文字で、プレースホルダーが多言語化できました。

<input type="text"
    :placeholder="$t('placeholder')">

02 t()メソッドに渡すパスに変数を含める

翻訳テキストを取り出す$t()メソッドの第1引数には、テキストが収められたプロパティのパスを渡します。ここに変数を含めるにはどうしたらよいかです。具体的には、v-forディレクティブで複数要素を変数からつくりたい場合でした。

<div id="app">
    <ul>
        <li
            v-for="city in cities"
            :key="city">
            <!-- message[city]のテキストを取り出したい -->
        </li>
    </ul>
</div>
const messages = {
    en: {
        message: {
            tokyo: 'Tokyo',
            newyork: 'New York',
            london: 'London'
        }
    },
    ja: {
        message: {
            tokyo: '東京',
            newyork: 'ニューヨーク',
            london: 'ロンドン'
        }
    }
}
// ...[中略]...
new Vue({
    i18n,
    data: {cities: ['tokyo', 'newyork', 'london']}
}).$mount('#app')

試したところ、つぎの記述で翻訳テキスト「東京」または「Tokyo」が表示されました。

{{ $t("message['tokyo']") }}

それならと、つぎのように書いてみると、また式が表れてテキストは取り出せません。

{{ $t("message[city]") }}

こちらは検索では見つけることができず、VueのForum(英語)で質問してみたところ回答が得られました。messagesオブジェクトの感覚で捉えていたのがよくなかったようです。文字列のパスと考えるべきでした。

{{ $t("message." + city) }}

ご参考までにテスト用のサンプルをCodePenに上げておきます。

サンプル001■ Vue I18n Test

See the Pen Vue I18n Test by Fumio Nonaka (@FumioNonaka) on CodePen.

Appendix TodoMVCを日英対応にする

Vue.js + CLI入門」は、公式サイト「TodoMVC の例」をVue CLIによる単一ファイルコンポーネント(vueファイル)でつくり直しました。さらに、これをVue I18nで日英対応にしたのが「Vue.js + Vue I18n: アプリケーションを多言語に対応(国際化)させる」の作例です。こちらはCodeSandboxに公開しています。興味がある方はリンクの解説をお読みください。

サンプル002■ vue-i18n-todo-mvc

FN1910002_007.png
>> CodeSandboxへ

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

Vue.js <lazy-component><コンポーネントのイベントが発火しない/></lazy-component>

コンポーネントを遅延読み込みしたい

Vueで遅延読み込みを実行してくれるライブラリであるVue-Lazyloadをコンポーネントモードで使っていて、つまりました。

main.vue
<div v-for="image of images" :key="image.index">
    <image-thumbnails @showModal="modalOn"/>
</div>

image-thumbnailsコンポーネントは画像のサムネイルを表示するコンポーネントで、サムネイルがクリックされるとshowModalイベントを発火します。
メインコンポーネントはshowModalイベントを検知すると、モーダルで画像を表示します。

サムネイルが多くなりそうなので、遅延読み込みしてほしいと思い、以下のように記述しました。

main.vue
<div v-for="image of images" :key="image.index">
    <no-ssr>
        <lazy-component>
            <image-thumbnails @showModal="modalOn"/>
        </lazy-component>
    </no-ssr>
</div>

なんということでしょう。
メインコンポーネントがimage-thumbnailsコンポーネントのshowModalイベントを検知できなくなりました。
多分、遅延読み込みのせいでイベント監視をバインドできなかったんでしょう。

内側に遅延処理を書く

次のように書いて解決しました。

main.vue
<div v-for="image of images" :key="image.index">
    <image-thumbnails @showModal="modalOn"/>
</div>
imageThumbnails.vue
<template>
    <no-ssr>
        <lazy-component>
            ....
        </lazy-component>
    </no-ssr>
</template>

遅延読み込みしたいコンポーネント内のルートにlazy-componentを記述すると、遅延読み込みされるし、イベント処理もうまくいきました。

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

Vue.jsを全く知らない状態から、とりあえず使ってみるまで

業務でVue.jsを使えないとメンテ出来ない事があるので、とりあえず使って概要を抑える
ことにしました。

とりあえず使えるようにする設定

インストール

Vue.js公式のインストールの項目に書いてある、CDNでのインストールを試します。

CDNでのインストールであれば、htmlのhead内に以下を書くだけで使用出来ました。

<head>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.0"></script>
</head>

vueインスタンスの生成

以下を追加する事でVue.jsインスタンスを作成する事が出来、実際に使用していく事が出来ます。

</body>
<script>
  var app = new Vue({
    // newしてvueインスタンスというものを作る。vueの処理はここに書いていく。
  })
</script>

今回はとりあえず使ってみる事が目的なので、Vue.jsの構文を</body>の下あたりに直接<script></script>で書いてしまいます。

データバインディング

データバインディングとは、データを同期させて表示に反映させる事。

まず、vueインスタンス内にel: '#id名'と書き、html内のidと紐づけてみます。

<body>
  <div id="app">
  </div>
</body>
<script>
  var app = new Vue({
    el: '#app' // id="app"を指定して、その配下のhtmlにVue.jsを反映させる
  })
</script>
</html>

データオプション作成とhtml内での展開

Vue.jsではvueインスタンス内にdataオプションでデータを定義した後、html内で{{ 展開したいdataのキー }}のように書く事でデータを展開して表示出来ます。

{{}}で囲って書く事をマスタッシュ構文と言います。

<body>
  <div id="app">
    {{ greet }}  // 3. 作ったデータをマスタッシュ構文で展開
  </div>
</body>
<script>
  var app = new Vue({
    el: '#app',
    data: {                 // 1. データオプションでデータを用意する
      greet: 'Hello Vue.js' // 2. greetというキーで'Hello Vue.js'というデータを作る
    }
  })
</script>
</html>

完成

最終的に以下のようになります。

<html>
  <head>
      <script src="https://cdn.jsdelivr.net/npm/vue@2.6.0"></script>
  </head>
  <body>
    <div id="app">
      {{ greet }}
    </div>
  </body>
  <script>
    var app = new Vue({
      el: '#app',
      data: {
        greet: 'Hello Vue.js'
      }
    })
  </script>
</html>

Vue.jsの基本構文

先ほどの完成形を以下のようにテンプレートとして使い、Vue.jsの基本構文を使ってみました。

<html>
  <head>
      <script src="https://cdn.jsdelivr.net/npm/vue@2.6.0"></script>
  </head>
  <body>
    <!--ここにhtmlとVue.jsの構文を書く-->
  </body>
  <script>
    // ここにVue.jsのデータを設定する
  </script>
</html>

v-bind

vueオブジェクト内に定義したdataオプションのキーをv-bind:valueに設定する事でデータを表示します。

  • html
<div id="app">
  <input type="text" v-bind:value="message">
</div>
  • Vue.js
var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue.js!'
  }
})

v-if

dataオプションで設定した真偽値によって表示、非表示を切り替えます。
下記の例だとon_offが偽の場合、pタグごと表示を消します。

  • html
<div id="app">
  <p v-if="on_off">
    Hello
  </p>
</div>
  • Vue.js
var app = new Vue({
  el: '#app',
  data: {
    on_off: true
  }
})

v-show

v-showはv-ifの例のように表示、非表示を制御出来ますが、タグ毎非表示にするのではなく、
display: none;にします。

  • html
<div id="app">
  <p v-show="on_off">
    Hello
  </p>
</div>
  • Vue.js
var app = new Vue({
  el: '#app',
  data: {
    on_off: true
  }
})

v-for 繰り返し

要素の個数分繰り返して表示出来ます。
dataオプションで設定した配列colorsを1つずつcolorに入れて表示します。

  • html
<div id="app">
  <ol>
    <li v-for="color in colors">{{ color }}</li>
  </ol>
</div>
  • Vue.js
var app = new Vue({
  el: '#app',
  data: {
    colors: ['Red', 'Greeen', 'Blue']
  }
})

v-on イベント処理

クリックされた時の動作など、イベント処理を設定出来ます。

  • html
<div id="app">
  <button v-on:click="on_click">
    クリックボタン
  </button>
</div>
  • Vue.js
var app = new Vue({
  el: '#app',
  methods: {
    on_click: function() {
      alert('クリックされました');
    }
  }
})

v-model 双方向バインディング

データを共有してリアルタイムで変更を反映します。
1つ目のテキストボックスに入力すると、dataオプションのtextが更新され、2つ目のテキストボックスにもすぐに反映されます。

  • html
<div id="app">
  <p>
    <input type="text" v-model="text"> // 1つ目のテキストボックス
  </p> 
  <p>
    <input type="text" v-model="text"> // 2つ目のテキストボックス
  </p> 
</div>
  • Vue.js
var app = new Vue({
  el: '#app',
  data: {
    text: 'Hello'
  }
})

まとめ、感想

とりあえず使ってみて、なんとなくこんな感じか?というところはわかりました。
でもQiitaにあるVue.jsでゲーム作る記事とか見てると、まだ全体の1%くらいしか理解してない感じがする^^;
とりあえず何かアプリを作りたいところです。

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

[初心者]Nuxt.jsビギナーズガイド Vue.js ベースのフレームワークによるシングルページアプリケーション開発

はじめに

noteのフロントエンドをNuxt.jsへ刷新します はもう昨年のことかと思いながら、Nuxt.jsを習得してみる。Universal Application、Progressive Web Applicationなど、これからのWebにとって当たり前の技術を身につける。

Nuxt.jsビギナーズガイド Vue.jsベースのフレームワークによるシングルページアプリケーション開発 を簡単にまとめてみた。JavaScript初心者の私でも非常に理解しやすく、Qiitaにいいねをつけていただいた上で、ご購入をおすすめします。

Nuxt.jsビギナーズガイド Vue.js ベースのフレームワークによるシングルページアプリケーション開発

1. Nuxt.jsの概要

01. 「モダンフロントエンド」のイマ

今日フロントエンドは非常に安定し停滞した状態が続いている。トラディショナルなサーバーがHTMLを返す時代から、SPAとAPIによるWebアプリケーションがデファクトスタンダードになった。当分はReact、Vue、Angularの寡占状態は変わることはなく、技術的にも枯れている。先進的な機能(Web Worker、Web Assembly)も追加されているが、実用段階まで民主化されてはいない。

モダンフロントエンドは、多種多様な選択肢があり柔軟な開発が可能。しかしそれは、アプリケーションの本質的な価値ではない領域と付き合い続ける必要があるともいえる。現在では、どの領域にも著名な技術がシェアを占めており、効率化することに妥当性を覚える段階では、開発者自身が技術を選定し続ける理由はない。

一部でしか使われていない技術(GraphQL)にも対応できるだけのアーキテクチャとエコシステム、コミュニティが求められている。Nuxt.jsは、その要件を満たしている。Vue.jsの記法や設計の資産をそのままに、負債となりやすい部分(webpack、モジュールの最適化、サーバーサイドレンダリング(SSR))までカバーしている。またサードパーティライブラリやVueプラグインによるアプリケーションのコア拡張も、ミドルウェアやプラグインといった独自システムによってメンタナリビリティの高い、統一的なアーキテクチャでの運用が可能。またVue.jsの範囲だけに限らず、Nuxt.js内に形成されたシンプルな拡張システムのもとにaxiosやJSON API、GraphQLサーバーへのリクエストなども可能。

02. Nuxt.jsとは

当初はVue.jsアプリケーション開発におけるSSRを支援することを目的として始まった。Next.jsはReactらしいUNIX文化を引き継ぎ、Nuxt.jsは規約をベースとしたAngularのようなフルスタックフレームワークの道を辿る。

2016年10月25日zeit.coのチームがReactアプリケーションをサーバーサイドレンダリングするためのフレームワークNext.jsを発表しました。その発表から数時間後、Next.jsと同じ方法で、Vue.jsアプリケーションをサーバーサイドレンダリングするアイディアが生まれました。すなわちNuxt.jsが誕生したのです。

※Zeit社は、ミニマルなNode.jsのサーバー構築ライブラリ microやElectron製のターミナル Hyper、Node.js/Dockerホスティングサービス Nowを開発、運用している企業である。

Nuxt.jsの特徴と機能

  • ビルドプロセスの隠蔽

Vue.jsによるSPA開発は、設定すべきビルド環境が多くwebpackを中心として多くのローダーやプラグインを導入、メンテナンスする必要がある。Nuxt.jsは、基本的にはすべての設定を所持、最適化した形でメンテナンスされており、webpackを意識する必要があるのはカスタマイズしたローダーやプラグインを追加したい場合だけ。

  • Vueのエコシステムとのインテグレーション

Vue.jsは、Vue Router、Vuex、Vue Server Renderer、vue-metaが密接に連携するように作られており、定型句をもとに個別設定する必要がある。Nuxt.jsは、すべてが設定されており、独自レイヤからも扱いやすいようにカスタマイズされている。

  • 独自レイヤの実装

独自レイヤは、Vue.jsの機能不足な部分を、Nuxt.jsが追加で実装した概念。例えば、middleware(アクセス時のフックとして機能する)は、内部で任意の処理やルーティングを改ざんすることが可能。SSR時は認証情報などに応じて柔軟に301/302リダイレクトを行う機能を提供し、SPAモードでは適切な初期データの格納などで利用できる。またVue.jsでは独自で設けるプラグイン領域は、pluginsディレクトリ内で包括的に管理できる。

03. Nuxt.jsがもたらすもの

Ruby on Railsは、規約の代表として広く知られている。暗黙知を大量に作ることを許容する代わりに、多くのWeb開発における頻出パターンを効果的に実装できる。同様にNuxt.jsは、Vue.js開発においての定型パターンを規約と定めている。例えば、「pagesディレクトリに置かれる.vueファイルはページを表す」という規約を守ることにより、開発者はVue Routerの煩雑な設定の記述とメンテナンスから開放される。また「data関数の代わりにasyncDataを利用する」という規約を守ることにより、簡単にSSRやアプリケーションとの連携に強いVueコンポーネントを開発できる。

つまり納得感のある、統一的な記述が守られる結果、多くのコスト(どちらでも良い設計の議論など開発におけるノイズから、単純なコードの記述量まで)を省略でき、効率的な開発に大きく寄与する。この規約に対する考え方は、Angularと近いものがある。両者は、JavaScript/TypeScriptらしさが好みなのか。他のエコシステムの資産を十分に活用して柔軟に対処したいのか、1つの設計の中ですべてを閉じて堅牢な形で運用したいのか程度の違いしかない。Nuxt.jsは比較的攻めの規約、Angularは守りの規約といえる。

04. Nuxt.jsがマッチするプロジェクトやシチュエーション

Vue.jsの中級者以上が1人でもいるVue.jsのSPAプロジェクトにはおすすめ。Vue.jsの柔軟さゆえに汎用性のない独自のアーキテクチャを考案・運用する代わりに、Nuxt.jsという1つのルールを中心に据えることで秩序のある開発が可能。またNuxt.jsでカバーできないものは、モジュールシステムを利用することでNuxt.jsのレールから逸脱しない。

メンバー間でVue.jsのレベル差が激しい場合にもおすすめ。Vue.jsは柔軟性ゆえバッドノウハウをつかみやすい。ベストプラクティスが分からない状況では、短期的な生産性の高い開発手法を選択してしまいがちだが、Nuxt.jsを利用することで短期的な生産性を落とすことなく効果的な設計を適用することが可能。

メンバー全員が初学者である場合とSPAでない場合はおすすめしない。規約によって整備されていて誰でも扱いやすいように見えるが、ミドルウェアやプラグインなど独自機能やVue.jsを拡張していることによる独自のライフサイクルなど、学習コストが高い。このような場合は、 Vue CLI を利用した開発をおすすめする。

2. Nuxt.jsによるシングルなアプリケーション開発

QiitaAPIを利用してNuxt.jsタグの投稿一覧を表示し、その投稿から投稿者のプロフィールと投稿一覧を表示するサービス。axiosを利用したHTTPリクエスト、動的なルーティングによるコンテンツの出し分け、SSR、SEO対策、Vuexストア(クラシックモード)を理解できる。

$ vue init nuxt-community/starter-template hoge

※サンプルアプリケーションの詳細な解説は、Nuxt.jsビギナーズガイドをご購入ください。

Nuxt.jsによるシングルなアプリケーション開発

3. Nuxt.jsの機能の活用

01. layoutsディレクトリによるレイアウトの共通化

Vue.jsでは共通化して効率化したいモチベーションと、共通化した際の編集コストや管理コストの増加という問題を天秤にかける。それに対してNuxt.jsは、簡単な切り分けや宣言的な記述方法によって、複雑な管理なしにレイアウトの共通化が可能。

default.vue をトップページ用に、個別ページを single.vue にした場合、すべてのコンポーネントに対して layout: 'single' を指定する必要があり適用忘れが生じる可能性が高い。トップページはLPやダッシュボードのサマリなど他のページとは大きく異なるデザインが多いため、トップページだけ layout: 'home' を指定することがベストプラクティス。大規模プロジェクトだと、default.vue を使わない方がわかりやすい場合もある。

※サンプルアプリケーションの詳細な解説は、Nuxt.jsビギナーズガイドをご購入ください。

c08fb065f34d44e2e6ee7b834fdf8cd9.gif

02. Nuxt.jsのライフサイクル

Nuxt.jsはアクセスがあった際に、次の図のようなライフサイクルを形成する。これらの処理が完了後、Vue.jsのライフサイクルが呼び出される。プラグインはさらに前に呼ばれる。ライフサイクルを意識することで、それぞれの責務を理解した開発が可能。

Nuxt.jsのライフサイクル

03. middlewareによるグローバルなフックの登録

middlewareは、機能面の追加としてもっとも強力な機能。グローバルを含めた任意のルーティングへのアクセス時の最初に読み込まれるため、SSR処理などが行われる前に様々な処理を行うことが可能。また default export によって、1つの関数を返すファイルにする必要がある。

今回は universal-cookie を用いて、簡単なログインを必要とするページを作成する。認証には contextオブジェクト を用いて、リクエストデータとrouteオブジェクトとredirect関数を受け取り実装する。

エンドポイント 認証の振り分け
http://localhost:3000/ 誰でもアクセス可能・それぞれのページへのリンクが存在する
http://localhost:3000/login 未ログインユーザーのみ・ログインしている場合は「/」へ
http://localhost:3000/authed-route ログイン済ユーザーのみ・ログインしているしていない場合は「/login」へ

※サンプルアプリケーションの詳細な解説は、Nuxt.jsビギナーズガイドをご購入ください。

middlewareによるグローバルなフックの登録

04. プラグインによるVue.jsプラグイン資産の有効活用

プラグインは、npmパッケージやVueプラグイン、特定の処理をグローバルに登録し再利用性を高めるために利用する。主にUIフレームワークやFirebase SDK、momentなど、必ずアプリケーション全体で利用するライブラリの導入時に利用する場合と、ルーティングフックや初期段階での外部CDNコードの読み込みなどの共通処理を実装する場合に利用する。メリットは、Nuxt.jsの規約の上で開発が可能なことと、SSR時に呼び出すかをオプションで簡単に切り替えることができること。

今回は、VueRouterのbeforeEachフック利用して、ページ遷移ごとにルーティングのパスをロギングしてみる。plugins: ['~/plugins/logger'] は、 plugins: [{ src: '~/plugins/logger', ssr: true }] と等価。実際の開発では、GoogleAnalyticsや mixpanel などの設定で利用する。

※サンプルアプリケーションの詳細な解説は、Nuxt.jsビギナーズガイドをご購入ください。

プラグインによるVue.jsプラグイン資産の有効活用

05. Vuexのモジュールモードを活用したオートローディング

  1. Nuxt.jsによるシングルなアプリケーション開発

で、Vuexストアのクラシックモードを利用した。自身でVuexを読み込み、ストアインスタンスを生成する形でVuexストアを構築する。本格的なアプリケーション開発ではモジュールモードを利用する。Vuexストア自体に関わるコードは一切記述せず、Vuexストア内で利用するモジュールのビジネスロジックのみ記述する。モジュールを規約に沿って記述しexportするだけで、自動的に名前空間付きのモジュールと解釈しVuexストアインスタンスを生成する。

モードと構造の判別は以下で行なっている。

  • index.jsはルートモジュールである
  • index.jsがオブジェクトをエクスポートしている、もしくは存在しない場合はモジュールモードで動作する。Vuexストアをインスタンスをエクスポートしている場合は、クラシックモードで動作する
  • index以外の名前を持つJavaScriptファイルは、ファイル名のスコープによるモジュールとして作用する

最終的に出力されるVuexストア構造は完全に同じであり、モジュールモードの方が構造について強く意識せずモジュールの記述に集中できる。

クラシックモード

store/users.js
new Vuex.Store({
  state: { isLoading: false },
  mutations: {
    setIsLoading(state, isLoading) {
      state.isLoading = isLoading
    }
  },
  modules: {
    users: {
      state: {
        list: []
      },
      mutations: {
        addUser(state, user) {
          state.list.push(user)
        }
      },
      actions: {
        addUser({ commit }, { user }) {
          commit('addUser', user)
        }
      }
    }
  }
})

モジュールモード

store/user.js
export const state = () => ({
  list: []
})

export const mutations = {
  addUser(state, user) {
    state.list.push(user)
  }
}

export const actions = {
  addUser({ commit }, { user }) {
    commit('addUser', user)
  }
}

4. 中規模以上の開発を意識したNuxt.jsによるWebアプリケーション開発

ブログサービスを作成する。バックエンドに Firebase Realtime Database を利用してAPIサーバを用意して、ユーザ情報と投稿といいねデータをやりとりできるようにする。フロントエンドでは、ElementUIを利用して全体の投稿の一覧や、ユーザごとの投稿の一覧を閲覧できるようにする。

$ create-nuxt-app hoge

プロジェクトのディレクトリをappディレクトリ配下にいれているのは、アプリケーションのコアコードとそれ以外のコードを明確にするため。また各種ツールのパス指定を簡潔にするため。例えば、Lintやコードフォーマット形式外の箇所を1つずつignoreする必要がない。

※サンプルアプリケーションの詳細な解説は、Nuxt.jsビギナーズガイドをご購入ください。

ブログサービス

5. Nuxt.jsアプリケーションのテスティング

01. フロントエンドにおけるテストの必要性

従来は、UI層と密接に関係しているためや外部のSDKを読み込むため、API接続があることためテストが難しかった。またSeleniumなどのe2eテストツールは存在したが、DOMやブラウザに強く依存するため、作成コストは高いがテストの寿命は短かった。

UTはVuexデータストアと挙動が複雑なVueコンポーネント、フレームワークに依存しないレイヤのコードをテストすべきである。Jestを利用すると良い。アサーションライブラリからテストランナー、カバレッジレポーター、スナップショットテストまで内包しており、特有の設定を覚える必要がない。

$ yarn add -D jest @vue/test-utils lodash.clonedeep babel-jest 'babel-core@^7.0.0-0' @babel/core babel-preset-vue-app vue-jest

6. アプリケーションのデプロイと運用

名称 モード 学習コスト 運用コスト メタタグ対応(SEO/OGP) 拡張の柔軟性
Universal(デフォルト) SSR 高い 高い ? ?
Generate SPA 低い 低い ?‍♂️ ?‍♂️
SPA SPA 非常に低い 低い ?‍♀️ ?‍♂️

デプロイ先はService Level Agreement(uptime)やレイテンシ、運用コストなど総合的な判断が必要。

SSR

静的サイト

(Netlify参考記事)
【爆速】静的ページを無料で独自ドメインでSSL(HTTPS)で公開する方法(Github => CircleCI => AWS S3 / Firebase Hosting / Netlify)

7. プラグインとモジュール、エコシステムの開発・貢献

  • @nuxtjs/axios
  • json-server
  • @nuxtjs/pwa

(PWA参考記事)
[Nuxt/WebSpeechAPI]騒がしい居酒屋でもワンタップで店員さんを呼ぶサービス「親指ですみません」

サードパーティモジュールの探し方は、以下リポジトリから探すのが良い。また本書では自作プラグイン・モジュールの開発からnpmへの公開まで記載されています。

8. 最新技術のキャッチアップのススメ

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

Vueのcomputedとmethodsを調べる

はじめに

業務でVue.jsを使っています。
Vueのdataを加工してブラウザに描画したいときcomputed(算出プロパティ)を使うと思いますが、methodsでも同じことができます。
じゃあ、computedとmethodsの違いってなんだろうと疑問が浮かんだので調べてみました。

結論

公式にありました。
https://jp.vuejs.org/v2/guide/computed.html

computedの場合はこうなって

算出プロパティは、リアクティブな依存関係が更新されたときにだけ再評価されます。

methodsの場合はこうなるんですね

対称的に、メソッド呼び出しは、再描画が起きると常に関数を実行します。

動きを確認してみる

とはいえ文字だけではイメージがつかめませんでした。
なので簡単なプログラムを書いてそれぞれの動きを確認してみます。

プログラムの仕様

学生の名前をブラウザに描画するプログラムです。
学生クラスを作り以下のフィールドを持たせます。

  • name: 学生の名前を表す
  • group: 学生のグループを表す(初期値は'')

そして所属するグループによって描画位置を変更します。

  • 無所属(groupが'')なら左
  • sun組(groupが'sun')なら真ん中
  • moon組(groupが'moon')なら右

ブラウザを最初に開いたときは全ての学生は無所属で、
学生の名前をクリックすると、セレクトボックスで選択中のグループの所属となります。

以下ソースで検証します。
グループ名は烈と豪にするか迷いました。

sample.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
  <h1>SUNとMOON</h1>
  <div id="app">
    <select v-model="selectedGroup">
      <option v-for="(item, index) in groups" :key="index">
        {{ item }}
      </option>
    </select>
    <div class="container" style="display: flex;">
      <div style="margin: 0px 10px">
        <h2> - </h2>
        <li v-for="(student, index) in noneGroup" :key="index">
          <span @click="setGroup(student, group)">
              {{ student.name }}
          </span>
        </li>
      </div>
      <div style="margin: 0px 10px">
        <h2>SUN組</h2>
        <li v-for="(student, index) in sunGroup" :key="index">
          {{ student.name }}
        </li>
      </div>
      <div style="margin: 0px 10px">
        <h2>MOON組</h2>
        <li v-for="(student, index) in moonGroup" :key="index">
          <span @click="setGroup(student, group)">
            {{ student.name }}
          </span>
        </li>
      </div>
    </div>
  </div>
  <script>
    class Student {
      constructor(name){
        this._name = name;
        this._group = '';
      }
      get name() {
        return this._name;
      }
      set group(group){
        this._group = group;
      }
      get group(){
        return this._group;
      }
    };
    var app = new Vue({
      el: '#app',
      data: {
        students: [
          new Student('a'),
          new Student('b'),
          new Student('c'),
          new Student('d'),
          new Student('e'),
        ],
        groups: ['sun', 'moon'],
        selectedGroup: '',
      },
      computed: {
        noneGroup() {
          console.log('none!')
          const obj = this.students.filter(e => e.group === '');
          return obj;
        },
        sunGroup() {
          console.log('sun!')
          const obj = this.students.filter(e => e.group === 'sun');
          return obj;
        },
        moonGroup() {
          console.log('moon!')
          const obj = this.students.filter(e => e.group === 'moon');
          return obj;
        },
      },
      methods: {
        setGroup(student, group) {
          if (group === '') return;
          student.group = group;
        },
      },
    });
  </script>
</body>
</html>

結果はどうなったか

computedの場合

セレクトボックスにバインドしているので、選択のたびにselectedGroupの値が変わります。
ただしselectedGroupが変更されても、それ以外の値は変わらないのでcomputedの関数は実行されません。
実行されるのはclick時のsetGroup()によって描画元の値が変更されたときです。
(最初にブラウザを開いたときにもcomputedが実行されてますが、わかりにくいので消しています)

computed_case.gif

ソース修正

では、methodsを使って描画したらどうなるか確認します。
computedに定義した関数をmethodsに移動させました。

methodsの場合
computed: {
},
methods: {
  setGroup(student, group) {
    if (group === '') return;
    student.group = group;
  },
  noneGroup() {
    console.log('none!')
    const obj = this.students.filter(e => e.group === '');
    return obj;
  },
  sunGroup() {
    console.log('sun!')
    const obj = this.students.filter(e => e.group === 'sun');
    return obj;
  },
  moonGroup() {
    console.log('moon!')
    const obj = this.students.filter(e => e.group === 'moon');
    return obj;
  },
},

methodsの場合

セレクトボックスを変更した段階で関数が実行されています。
もちろんclick時にsetGroup()で値が変更された時も関数が実行されています。
つまり描画元に関係ない値が変更されたときも再計算されていることがわかります。
なるほどなー。

methods_case.gif

おわりに

いままでなんとなくcomputedを使っていましたが動きを比較すると違いがよくわかりました。
もしこれが「商品一覧をセレクトボックスの値でソートする」だったら計算量が大変なことになりそうです。
特別な理由がない限りcomputedを使った方がよさそうですね。

参考

Vue.js公式サイト: https://jp.vuejs.org/v2/guide/computed.html

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

vue.js 現在のパスを取得する

現在のパスを取得する

現在のパスは、

this.$route.path

で取得出来る。

スクリーンショット 2019-10-08 10.43.37.png

リファレンス
https://router.vuejs.org/ja/api/#router-onerror

現在のパスによってリダイレクト先を変える関数

some_component.vue
redirectToRoot: function() {

  // 現在のパスを取得
  console.log(this.$route.path)

  if (this.$route.path === '/')
    this.$router.push({ path: '/home' })
  else
    this.$router.push({ path: '/' })
  this.$router.go({ path: this.currentRoutePath })
  }
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Nuxt.jsでaxiosの共通処理を作成し、API呼び出し処理をラップして使用する

Nuxt.jsでAPIを叩くとき、共通のヘッダーとか設定したいですよね?
さらにAPIの呼び出しをラップして、 api.getUser(1) みたいな感じで使いたかったので、いろいろ試した際の備忘録です。
酔っ払いながら試したので、忘れないうちにメモっておきます。

Nuxt.js歴は数週間の初心者なので、「もっとこうした方がいいよ!」とかアドバイスありましたら教えていただきたいです!

ということで今回は、下記を目的としています。

  • APIを叩く際に共通のAuthorizationヘッダーを付ける
  • APIの呼び出し処理をラップして、Component内でより手軽に呼び出させるようにする

ディレクトリ構成

/plugins 内に、下記のような構成でファイルを置きます。

plugins
└─ axios
    ├─ modules
    │   ├─ user.js   # user関係のAPI処理
    │   ├─ hoge.js   # hoge関係のAPI処理
    │   └─ fuga.js   # fuga関係のAPI処理
    └─ index.js      # 共通処理の記述

user.js とか hoge.js とかファイルを分けていますが、関連するAPIの処理をファイル毎にまとめたかったのでこんな感じにしてます。

nuxt.config.js に設定を追加

pluginsの箇所に追加

nuxt.config.js
  plugins: [
    '@/plugins/axios/index'
  ],

axios 共通処理部分の作成

axiosで共通処理を作成するには、Interceptorsという機能を使います。

plugins/axios/index.js
export let axios;
export let state;

export default function({ store, $axios }) {
  $axios.onRequest(config => {
    config.headers.common['Authorization'] = `Bearer token`;
    config.headers.common['Accept'] = 'application/json';
  });

  $axios.onResponse(response => {
    return Promise.resolve(response);
  })

  $axios.onError(error => {
    return Promise.reject(error.response);
  });

  axios = $axios;
  state = store.state;
}

Auth Moduleを使用して、Authorizationヘッダーに付けるトークンをstoreに保存しておくと、いい感じに実装できると思います。

APIを呼び出す部分の作成

とりあえず、特定のユーザーを取得する getUser と、ユーザー一覧を取得する getUsers という処理を作成するものとします。
user関係の処理なので、 user.js にまとめようと思います。

plugins/axios/modules/user.js
import { axios } from '../index.js';
import { state } from '../index.js';

export default {
  getUser(id) {
    return axios.$get(`users/${id}`)
  },

  getUsers() {
    return axios.$get(`users`)
  }
}

plugins/axios/index.js でexportした axios をimportして使用しています。
state は使用していませんが、一応使いたい時は使えるという感じで。。

実際にComponent内で利用する

上記で作成した getUser をComponent内で使用したい場合は、例えば下記のように関数を定義して呼び出すことができます。

pages/index.vue
<script>
import UserApi from '@/plugins/axios/modules/user'
export default {
  methods: {
    getUser(id) {
      UserApi.getUser(id).then((response) => {
        console.log(response)
      }).catch((error) => {
        console.log(error)
      })
    }
  }
}
</script>

以上でやりたかったことはできました!

まだまだNuxt.jsは触り始めたばかりですが、とても楽しいです!
もっと効率良くできるよーなどアドバイスあれば、ぜひ教えていただきたいです。

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