20200929のvue.jsに関する記事は4件です。

Nuxt.jsで認証認可入り掲示板APIのフロントエンド部分を構築する #6 記事投稿フォームの作成

Nuxt.jsで認証認可入り掲示板APIのフロントエンド部分を構築する #5 ログイン・ログアウトの実装

はじめに

今回はNuxt編の最終回。
記事投稿フォームをindexに設置します。

ログインしていないと書き込めないので、ログイン中のみフォームを表示します。

Railsのレスポンスコード修正

まず下準備として、Rails側の修正漏れ箇所を直します。
postのsave失敗時、ステータスが200(正常)で返ってきてしまっておりエラーがキャッチできないので、レスポンスコードを422で返すようにします。

app/controllers/v1/posts_controller.rb
...
       if post.save
         render json: post
       else
-        render json: { errors: post.errors }
+        render json: { errors: post.errors }, status: 422
       end
     end
...
       if @post.update(post_params)
         render json: @post
       else
-        render json: { errors: @post.errors }
+        render json: { errors: @post.errors }, status: 422
       end
     end
...

postした時にNuxt側でtry catchを使っていますが、エラーが出てもレスポンスコードが200だとcatchブロックに行きません。ここは以前の設定ミスなのであらかじめ塞いでおきます。

pages/index.vueとstore/index.jsの修正

pages/index.vue
       sm8
       md6
     >
+      <form v-if="logged_in" @submit.prevent="newPost">
+        <v-card>
+          <v-card-title class="headline">
+            新規投稿
+          </v-card-title>
+          <v-card-text>
+            <ul v-if="errors">
+              <li v-for="(message, key) in errors" :key="key">
+                {{ key }}
+                <span v-for="(m, i) in message" :key="i">
+                  {{ m }}
+                </span>
+              </li>
+            </ul>
+            <v-text-field
+              id="subject"
+              v-model="subject"
+              label="subject"
+              name="subject"
+              prepend-icon="mdi-subtitles"
+            />
+            <v-textarea
+              id="body"
+              v-model="body"
+              label="body"
+              name="body"
+              prepend-icon="mdi-comment-text"
+            />
+          </v-card-text>
+          <v-card-actions>
+            <v-spacer />
+            <v-btn color="primary" type="submit">
+              投稿
+            </v-btn>
+          </v-card-actions>
+        </v-card>
+      </form>
       <v-card v-for="post in posts" :key="post.id">
         <v-card-title class="headline">
           <n-link :to="`/posts/${post.id}`">
...
 <script>
 export default {
+  data () {
+    return {
+      subject: '',
+      body: '',
+      errors: []
+    }
+  },
   computed: {
     posts () {
       return this.$store.getters['posts/posts']
+    },
+    logged_in () {
+      return this.$store.getters.logged_in
+    }
+  },
+  methods: {
+    async newPost () {
+      try {
+        await this.$store.dispatch('posts/newPost', {
+          subject: this.subject,
+          body: this.body
+        })
+        this.subject = ''
+        this.body = ''
+        this.errors = []
+      } catch (e) {
+        this.errors = e.data.errors
+      }
+      const posts = await this.$store.dispatch('posts/fetchPosts')
+      this.$store.commit('posts/setPosts', posts.posts)
     }
   }
 }

エラーメッセージの表示箇所や、投稿後のposts再取得あたりがやっつけ感満載ですが。
やっていることはログインフォーム等と大差無いですね。

最後にstore/posts.jsにnewPostを定義して終わりです。

store/posts.js
 export const actions = {
   async fetchPosts () {
     return await this.$axios.$get('/v1/posts')
+  },
+  async newPost (_c, post) {
+    return await this.$axios.$post('/v1/posts', post)
   }
 }

終わりに

今回でNuxt.js編最終回です。
Rails編からご覧いただいていた場合、18+6で24章にも及ぶ連載です。ご覧いただいたり、プログラムを書いていただいた皆様ありがとうございました。

Railsで実装したCRUD処理でNuxt側未実装の点も多いため、ここからは自力で実装に挑戦してみてください。

また、RailsもNuxtも(特にNuxtは)初心者でお見苦しいコードも多々あったかと思いますが、これをきっかけにオリジナルのアプリケーション構築への挑戦をオススメします。

終わり

連載目次へ

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

Vue 映画情報をTMDb APIを使って取得

はじめに

完成イメージはこんな感じ

環境

Vue v2系です。

どうやら2020/09現在、vue v3系ではvuetifyが使えないようなので、あえてv2系にしました。。
https://github.com/vuetifyjs/vuetify-loader/issues/127

使えるようになってら、コメントより教えてください:blush:

別に「vuetifyなんて使わない」と言う方は、特にバージョンを気にしなくて良いかと!

vuetifyを入れる

コマンドプロンプトかターミナルより、プロジェクトvueの階層へ移動

vue add vuetify

TMDbのAPI keyを取得

【Ionic + Angular】TMDb APIで映画の一覧を取得して表示する
上記リンクのリンクより、取得できます。

映画情報を取得

axiosを入れる

npm install axios

まぁ映画上を取得するだけならaxiosを使う必要はなさそうですが、後々に検索機能とかもやってみたいので:smile:

一覧を表示してみる

Home.vue
<template>
    <v-container>
        <v-row>
            <v-col v-for="movie in movies" :key="movie.id">
                <v-card>
                    <v-img v-bind:src="'http://image.tmdb.org/t/p/w300/' + movie.poster_path"></v-img>
                    <v-card-title>{{ movie.title }}</v-card-title>
                    <v-card-subtitle>{{ movie.release_date }}</v-card-subtitle>
                    <v-card-text>{{ movie.overview }}</v-card-text>
                </v-card>
            </v-col>
        </v-row>
    </v-container>
</template>

<script>
import axios from 'axios'

export default {
    name: 'Home',
    data() {
        return {
            movies: [],
         // 自分のkeyに置き換える
            apiKey: '***',
        }
    },
    methods: {
        getMovies() {
            // &language=jaで日本語に(日本語版がないものは空欄になるけど、、)
            axios.get(`https://api.themoviedb.org/3/movie/now_playing?api_key=${this.apiKey}`)
            .then(response => {
                this.movies = response.data.results
                console.log(this.movies);
            })
            console.log(this.movies);

        },
    },
    created() {
        this.getMovies();
    }
}
</script>

https://developers.themoviedb.org/3/movies/get-now-playing
:point_up:ドキュメントはこちら

現在上映中の映画を取得しました〜。

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

@nuxtjs/composition-apiと@nuxt/contentを使ってみる

@nuxtjs/composition-api / @nuxt/content とは

Nuxt v2.13(2020-06-19)辺りから使えるレベルになってきている様子
nuxt2.13.0.png

専用のページもある

@nuxtjs/composition-api の概要

  • Vue 3 のComposition APIをNuxtの仕様に合わせたもの

@nuxt/content の概要

  • MarkdownやJSONなどのファイルからAPIのようにfetchできるようにするもの

create-nuxt-app を使用してnuxtアプリを生成

https://github.com/nuxt/create-nuxt-app
1.Package manager: Yarn
2.Programming language: TypeScript
3.UI framework: Vuetify
4.Nuxt.js modules: Axios / PWA / Content
5.Linting tools: ESLint / Prettier / Lint staged files / StyleLint
6.Testing framework: Jest
7.Rendering mode: Universal(SSR / Static)
8.Deployment target: Server
9.Deployment tools: none

@nuxt/contentはmodulesへ記載される

@nuxtjs/composition-apiをインストールする
https://composition-api.nuxtjs.org/setup

追記する

nuxt.config.ts
buildModules: [
  // https://github.com/nuxt-community/composition-api
  '@nuxtjs/composition-api',
],

試したリポジトリ
https://github.com/seiy4/nuxt214/tree/master/src

directry-structure.png

@nuxtjs/composition-api

https://www.npmjs.com/package/@nuxtjs/composition-api
https://github.com/nuxt-community/composition-api/blob/main/src/entrypoint.ts
nuxt-entrypoint.png

componentを定義

components/TheUser.vue
<template>
  <div>Name: {{ fullName }}, Message: {{ message }}</div>
</template>

<script lang="ts">
import { defineComponent, computed, ref } from '@nuxtjs/composition-api'

interface User {
  firstName: string
  lastName: string
}

export default defineComponent({
  props: {
    user: {
      type: Object as () => User,
      required: true,
    },
  },

  setup({ user }) {
    const fullName = computed(() => `${user.firstName} ${user.lastName}`)
    const message = ref('This is a message')

    return {
      fullName,
      message,
    }
  },
})
</script>
components/TheCounter.vue
<template>
  <div>
    <v-btn @click="decrement">-</v-btn>
    <span>{{ count }}</span>
    <v-btn @click="increment">+</v-btn>
  </div>
</template>

<script lang="ts">
import { reactive, computed } from '@nuxtjs/composition-api'

export default {
  setup() {
    const state = reactive({
      count: 0,
    })
    const count = computed(() => state.count)

    return {
      count,
      increment() {
        state.count++
      },
      decrement() {
        state.count--
      },
    }
  },
}
</script>

実際に使うとき

main.vue
<template>
  <div>
    <the-counter />
    <the-user :user="user" />
  </div>
</template>

<script>
export default {
  data() {
    return {
      user: {
        firstName: 'Taro',
        lastName: 'Yamada',
      },
    }
  },
}
</script>

@nuxt/content

https://content.nuxtjs.org/ja/writing
content ディレクトリへMarkdownを追加する

Code

hello.vue
<template>
  <div>
    <h3>{{ page.title }}</h3>
    <nuxt-content :document="page" />
  </div>
</template>

<script>
export default {
  async asyncData({ $content }) {
    const page = await $content('hello').fetch()

    return {
      page,
    }
  },
</script>

markdown sample

markdown-sample.png

output

nuxt:content-output.png

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

分かりすぎるVue.jsチートシート

自己紹介

むちゃんです。
関西を拠点に活動しているフロントエンドエンジニアです。

HAL大阪の2回生です:boy_tone2: (2020.9.29現在)

イベントなど回っているので是非大阪辺りの方は会いましょう!!

1...JSフレームワークについて

「Angular」,「React」,「Vue」この3個がJS人気フレームワークです。
今回はその中のVueについて詳しく話していきたいと思います
js.jpeg

Vueの公式ドキュメント

2...Vue.jsとは?

Vue.jsユーザーインターフェースを構築するためのJavaScriptのフレームワークです。
最近ではReactAngularVue.jsがJavaScriptの人気フレームワークとして定着してきています。
その中でもVue.jsは初心者に優しく比較的に学習しやすい事もあり現在の国内での人気は頭一つ抜けている印象があります。

Vue.jsの特徴

・コンポーネントの再利用性が高い
・学習コストが低く、取っ付きやすい
・拡張性が高い

3...Vue.jsで抑えとくべきポイント

①Vuex

Vuex は Vue.js アプリケーションのための 状態管理パターン + ライブラリです。
※貯蔵庫的な役割と思っていいです。

詳しいのは公式=>https://vuex.vuejs.org/ja/

Vuexの流れ(図解)

vuex.png

①componentでdispatchする
②actionsでAPIデータのやり取りする
③それをcommitしてmutationsを呼ぶ
④mutationsでデータの値変える
⑤するとstateの値が変わる

ざっくりした流れですが公式の補足程度で見てもらえると嬉しいです。

⭐️おすすめ
[初めてのアウトプット]
爆速理解!超簡単Vuex入門①


②基本的に使うオブジェクト構成

構造だけまとめているので詳しいことは公式で確認してください。

sample.js
ver vm = new Vue({
  el: 'app',
// ①使用するデータ
  data: {
    name: 'note',
    price: 500
  },
// ② 算出プロパティ
  computed: {
     isPrice: function () {
      return this.price / 2;
    }
  },
  // ③ 使用するメソッド
  methods: {
    isPrice: function() {
      return this.price / 2;
    }
  }
})

※thisについての記事

data(使用するデータ)

sample.js
var vm = new Vue ({
  el: '#app',
  data: {  //data: { プロパティ名: 値 }
    name: 'note',
    price: 500
  }
})
samole.html
<div id="app">
  <p>{{ name }}</p>
</div>

computed (算出プロパティ)

sample.js
var vm = new Vue ({
  el: '#app',
  data: {
    name: 'note',
    price: 500
},

  computed: {
    // isPriceを定義
    isPrice: function () {
      return this.price / 2;
    }
  }
})
sample.html
<div id="app">
  <!-- 250が表示される -->
  <p>{{ isPrice }}円</p>
</div>

methods(メソッド)

sample.js
var vm = new Vue ({
  el: '#app',
  data: {
    name: 'note',
    price: 500
},
  methods: {
    // メソッドisPriceを定義
    isPrice: function() {
      return this.price / 2;
    }
  }
})
sample.html
<div>
  <!-- ボタンをクリックするとisPrice関数が実行 -->
  <button @click="isPrice()">半額</button>
  <!-- 250円と表示 -->
  <p>{{ price }}円</p>
</div>

computedとmethodsの違い

算出プロパティとメソッドの使い分け

結論 & 資料

この辺りをある程度理解できればアウトプットに全力を注いでいいと思います。

⭕️ アウトプットやオススメの記事一覧

Vue.jsを100時間勉強して分かったこと
5分でわかるVue.js基礎の基礎
2019年版Vue.jsを使ってる人には必ず知っていてほしいVue.jsの武器
Vue-routerを使って、SPAをシンプルにはじめてみる
vueとexpressでSPAを作る

あとがき

今回は自分なりにVueについて簡潔にまとめてみした:thumbsup_tone2:

次回はReactについてまとめてみたいと思います。

Twitter @HomgMuchan ぜひフォロー待っています❗️

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