質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Nuxt.js

Nuxt.jsは、ユニバーサルなSPAが開発可能なVue.jsベースのフレームワーク。UIの描画サポートに特化しており、SSRにおけるサーバーサイドとクライアントサイドのUIレンダリングなどさまざまな機能を持ちます。

Q&A

解決済

3回答

3110閲覧

asyncDataとmethodsで被る処理がある場合の共通化する書き方を知りたいです。

tomomo

総合スコア430

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Nuxt.js

Nuxt.jsは、ユニバーサルなSPAが開発可能なVue.jsベースのフレームワーク。UIの描画サポートに特化しており、SSRにおけるサーバーサイドとクライアントサイドのUIレンダリングなどさまざまな機能を持ちます。

0グッド

1クリップ

投稿2020/11/01 10:40

nuxtを勉強しており、以下はajaxでデータを取ってきてそれをテーブルに表示するだけの処理です。

※以下ではvuetifytypescriptを使ってますが今回の質問にはさほど関係ないのでないのであえてタグは付けませんでした。

vue

1<template> 2 <v-row justify="center" 3 align="center"> 4 <v-col cols="12"> 5 <v-btn @click="redrawBlogs"> 6 redraw 7 </v-btn><!-- @REVIEW 再描画ボタン --> 8 <v-data-table 9 :loading="loading" 10 :headers="headers" 11 :items="items" 12 :items-per-page="10" 13 class="elevation-1" /> 14 </v-col> 15 </v-row> 16</template> 17 18<script type="ts"> 19import Vue from 'vue'; 20 21export default Vue.extend({ 22 data: () => ({ 23 loading: false, 24 headers: [ 25 { 26 text: 'id', 27 align: 'start', 28 sortable: false, 29 value: 'id' 30 }, 31 { 32 text: 'TITLE', 33 sortable: true, 34 value: 'title' 35 }, 36 ], 37 items: [] 38 }), 39 created () { 40 this.redrawBlogs(); // @REVIEW 初期の描画 41 }, 42 methods: { 43 async fetchBlogs () { 44 const response = await this.$axios.get('/api/blogs'); 45 return response.data || []; 46 }, 47 async redrawBlogs () { 48 this.loading = true; 49 const data = await this.fetchBlogs(); 50 this.items = data; 51 this.loading = false; 52 } 53 } 54});

createdで初期表示時のデータを取得しています。
nuxtにはasyncDataなるものがあり、createdを削除し下記のコードに置き換えました。

vue

1 async asyncData ({ $axios }) { 2 const response = await $axios.get('/api/blogs'); 3 return { items: response.data || [] }; 4 },

すると初期化前に実行されるのでデータが取れた状態から表示できます。
しかし、$axiosの部分が冗長になり、仮に修正があった際は2か所直さなければなりません。

vue

1 const response = await this.$axios.get('/api/blogs');

asyncDataはthisは使えないし、methodsも呼び出せない。(←あってますよね?)
上記のようなケースでもう少しいい組み方はあるのでしょうか?

よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

自己解決

一応これで共通化はできる。
さらにいいやり方あるのかもしれないけど、今の自分には多分これが限界かな。
回答来ないので一旦これで終了で。。。

  • /api/modules/blog.ts

vue

1import { axios } from '~/plugins/axios'; 2 3export default { 4 async page (params: { [key: string]: string } = {}) { 5 return await axios.get('blogs', { params }); 6 },
  • /api/index.ts

vue

1import blog from './modules/blog'; 2 3export { 4 blog as blogApi, 5};
  • /pages/blog.ts

vue

1<script type="ts"> 2import Vue from 'vue'; 3import { blogApi } from '~/api'; 4 5export default Vue.extend({ 6 async asyncData ({ app }) { 7 const response = await blogApi.page(); 8 : 9 } 10 : 11 methods: { 12 async fetchBlogs () { 13 const response = await blogApi.page(); 14 }, 15 :

投稿2020/11/07 14:27

tomomo

総合スコア430

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

自己解決したので記載します。
が、もっといい方法やこのやり方の懸念点がある場合、教えていただければ幸いです。

自分がやった方法
拡張したプラグイン(今回のケースではaxios)を作成する。

vue

1// ~/plugins/api.ts 2import { NuxtConfig } from '@nuxt/types'; 3import { NuxtAxiosInstance } from '@nuxtjs/axios'; 4 5export default function ( 6 { $axios }: NuxtConfig, 7 inject: (arg0: string, arg1: { getBlogs: () => Promise<any>; }) => void 8) { 9 const api = $axios.create({}); 10 (<NuxtAxiosInstance> api).setBaseURL('/api/'); 11 12 // @TODO 下記はとりあえずテスト用に用意しただけ。後でもっときちんと書く。 13 async function getBlogs (params: { [key: string]: string } = {}) { 14 return await api.get('blogs', { params }); 15 } 16 17 inject('api', { getBlogs }); 18}

で、それを有効にする。

vue

1// nuxt.config.ts 2plugins: ['~/plugins/api'],

すると$apiというのが使えるようになり、asyncDataとmethods、其々以下のように置き換えることが出来き、冗長が解消されました。

vue

1async asyncData ({ app }) { 2 // const response = await $axios.get('/api/blogs'); 3 const response = await app.$api.getBlogs(); 4 return { items: response.data || [] }; 5}, 6 7methods: { 8 async fetchBlogs () { 9 // const response = await this.$axios.get('/api/blogs'); 10 const response = await this.$api.getBlogs(); 11 return response.data || []; 12 },

投稿2020/11/04 01:32

編集2020/11/04 01:44
tomomo

総合スコア430

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tomomo

2020/11/04 01:49

...あ、これダメだ。 冗長は解消はしてるけど、getBlogsの部分でapiナンタラって書いてしまってるのでアクセス処理を全てこのファイルにズラズラ書かなきゃならない。 処理はimportしてみたいなのを考えてた。 引き続き、解答を求めます。。。
guest

0

vuexを使われてはいかがでしょうか?
コードがすっきりしますし、axiosで取得したデータも他のコンポーネントで使用することができます。

また、axiosのコードはメソッドとして一々呼び出すのではなく、
data-tableに表示するのであれば、createdやmountedを使用するのが良いかと思います。
こちらの記事が参考になると思いますので、参考まで

createdとmountedの違いについて

投稿2020/11/02 05:58

takochan1192

総合スコア100

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tomomo

2020/11/02 08:08

回答ありがとうございます。 asyncDataを使用しようとしたのはページコンポーネントの初期化前に実行されるという部分でメリットを感じたからです。データ読み込んだ後に全部表示されるという部分で。 上にあげたようなレベルのであれば別にcreatedでもいいじゃないかとも思われるでしょうが、そういう冗長が発生する場合、asyncDataではthisもmethodsも使えないので分離されてしまい、どのように書けば(設計すれば)いいのだろうか?というのが質問の趣旨です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問