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

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

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

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

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

Q&A

解決済

1回答

1162閲覧

[Vue.js]リストページのID要素を頼りに個別ページへ遷移させる方法

退会済みユーザー

退会済みユーザー

総合スコア0

Vue.js

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

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

0グッド

0クリップ

投稿2017/08/18 15:21

編集2017/08/19 18:34

Vue.jsで資格の過去問題解説アプリを作成したいと考えています。
リストの問題がクリックされたとき、個別の詳細ページに遷移させたいです。

###DynamoDBの設定
検索に解説本文を含めてしまうとDynamoDBで多くのリソースを消費してしまうため、リスト&検索用(questionListData)と詳細用(questionDetailData)の2つのテーブルを作成しています。それぞれのデータ形式は下記の通りです。

(questionListData)

JSON

1{ 2 "q_year" : "2012", 3 "q_no" : "1", 4 "category" : "english", 5 "q_title" : "QUESTION_TITLE", 6 "q_id" : "2012q001" 7 }, 8 { 9 "q_year" : "2012", 10 "q_no" : "2", 11 "category" : "english", 12 "q_title" : "QUESTION_TITLE", 13 "q_id" : "2012q002", 14 },

(questionDetailData)

JSON

1{ 2 "q_id" : "2012q001", 3 "q_body" : "QUESTION_BODY", 4 "q_desc" : "QUESTION_DESCRIPTON", 5 "image_url" : "", 6 "image_alt" : "" 7 }, 8 { 9 "q_id" : "2012q002", 10 "q_body" : "QUESTION_BODY", 11 "q_desc" : "QUESTION_DESCRIPTION", 12 "image_url" : "", 13 "image_alt" : "" 14 },

上記のデータをBoto3を使って、それぞれのDynamoDBのテーブルに格納しています。Serverlessフレームワークのofflineプラグインを使って、ローカル環境でAPI Gatewayを実行しています。Postmanでそれぞれのエンドポイントから適切にデータが取得できることを確認しています。

例えば、「http://localhost:3000/questions/2012」とすると、2012年の全ての問題が取得できます。同様に「http://localhost:3000/question/2012q001」とすると、2012年1問目の問題が取得できます。

実現したいのは、**リストのq_idを詳細用の「http://localhost:3000/question/{q_id}」に当てはめて、リストページからそれぞれの個別ページに遷移させること**です。

###Vuejsの設定
現在のVueの構造と希望の形を簡単なイメージにしてみました。
Vue構造と希望

まずリスト用データはRootInstance(main.js)でAxiosを使って読み込んでいます。これをdataでquestionsとしてOverview、QuestionListと下層に流しています。

javascript

1import Vue from 'vue' 2import VueRouter from 'vue-router'; 3import Axios from 'axios'; 4 5Vue.use(VueRouter); 6Vue.use(Axios); 7 8import routes from './util/routes'; 9const router = new VueRouter({routes}); 10 11new Vue({ 12 el: '#app', 13 data: { 14 questions: [] 15 }, 16 created() { 17 Axios.get('http://localhost:3000/questions/2012').then(response => { 18 this.questions = response.data 19 }); 20 }, 21 router 22});

QuestionList.vueでは下記のようにして、2012年度分のデータを表示することができました。一応<router-link>で囲っていますが、当然詳細ページに遷移することはできません。

javascript

1<template> 2 <div class="list"> 3 <h1>QuestionList page.</h1> 4 <div v-for="question in questions" v-bind:question="question.question"> 5 <router-link> 6 <h2>{{ question.q_title }}</h2> 7 </router-link> 8 </div> 9 </div> 10</template> 11 12<script> 13 export default { 14 name: 'QuestionList', 15 props: ['questions'] 16 } 17</script>

Axiosの公式ドキュメントなどから、paramsにq_idを指定して下記のような形になるのかなーと想像しますが、まだ具体的な解決ができずにいます。

axios.get('http://localhost:3000/question/', { params: { id: question.q_id } })

リストデータを読み込む階層など、改善の余地は多々あるかと思いますが、「リストページからq_idを頼りに詳細ページへ遷移する方法」を教えて頂ければなと思います。

有用そうなソースも歓迎です。

###[2017/08/19追記 ページ遷移できました]
aro10さんの指摘に沿って次のように修正し、ページを遷移させることができました。

Vue-RouterのPath設定に誤りがありました。

(修正前) { path: '/question/:id', component: QuestionDetail, name: 'detail'}

(修正後) { path: '/question/:q_id', component: QuestionDetail, name: 'detail'}

上記のようなルート定義を作成したうえで、QuestionList.vueのrouter-link部分を下記のように修正したところ、無事ページ遷移させることができました。

javascript

1<template> 2 <div class="list"> 3 <h1>QuestionList page.</h1> 4 <div v-for="question in questions" v-bind:question="question.question"> 5 <router-link :to="{ name: 'detail', params: {q_id: question.q_id}}"> 6 <h2>{{ question.q_title }}</h2> 7 </router-link> 8 </div> 9 </div> 10</template> 11 12<script> 13 export default { 14 name: 'QuestionList', 15 props: ['questions'] 16 } 17</script>

###ページ遷移と同時に詳細用API(/question/{q_id})を発火したい
アドバイスによりページ遷移が完了しましたが、現状では詳細情報を取得するためのAPI(http://localhost:3000/question/{q_id})が未発火なので、遷移先のページが空白のままです。

RootInstanceのcreated()で2012年の問題群を取得したように、ページ遷移したと同時にq_idを上記APIの{q_id}に代入して個別問題を取得したいと考えているのですが、どのような方法が考えられるでしょうか。動作こそしないものの、現在のDetailのコードなども早めに追記しようと思います。

※動作しないので参考にしないでください。
とりあえず詳細データのq_bodyを表示させたいと考えています。現状は詳細情報が取得されておらず、questionが空の状態なので、<div v-else>が実行されて、ページに「No Page.」と表示だけされています。

javascript

1<template> 2 <div class="detail"> 3 <div v-if="question != null"> 4 <h2>{{ this.question.q_body }}</h2> 5 </div> 6 7 <div v-else> 8 <p>No Page.</p> 9 </div> 10 </div> 11</template> 12 13<script> 14 15 export default { 16 name: 'detail', 17 props: ['questions'], 18 created() { 19 axios.get('http://localhost:3000/question/{q_id}', { 20 params: { 21 q_id: question.question.q_id 22 } 23 }) 24 .then(function(response) { 25 console.log(response); 26 this.question = response.data 27 }) 28 .catch(function(response) { 29 console.log(error) 30 }); 31 } 32 } 33</script>

###詳細ページの編集中、リストから受け取ったq_idが組み込めず…
this.$route.params.q_idという便利なアクセス手法があるとのこと。
これを利用してAPIの{q_id}に値を組み込めば簡単に行くのではないかと思ったものの、苦戦しています。Vue Devtoolを見る限り、詳細ページは確かにリストからq_idのパラメータを受け取っているものの、活用することがなかなかできません。

少し理解が追いついていない現状ですが、現在のコードは下記のようになっています。

(詳細用ページ)

javascript

1<template> 2 <div class="detail"> 3 <div v-if="question != null"> 4 <h2>{{ question.q_body }}</h2> 5 </div> 6 7 <div v-else> 8 <p>No Page.</p> 9 </div> 10 </div> 11</template> 12 13<script> 14 import axios from 'axios'; 15 16 export default { 17 name: 'detail', 18 data() { 19 return { 20 question: null 21 } 22 }, 23 mounted() { 24 this.getQuestion(this.q_id).then(question => this.question = question); 25 }, 26 beforeRouteUpdate(to, from ,next) { 27 this.getQuestion(to.params.q_id).then(question => this.question = question); 28 next(); 29 }, 30 methods: { 31 getQuestion(q_id) { 32 return axios.get("http://localhost:3000/question/", { 33 params: { 34 q_id: this.$route.params.q_id 35 } 36 }) 37 .then(function (response) { 38 question = response.data 39 }) 40 .then(function (error) { 41 console.log("http request denied"); 42 }); 43 } 44 } 45 } 46</script>

※まだ使い方をよく理解してはいませんが、beforeRouteUpdateがwatchと同じような働きをするとのことなので、参考にしたサイトに習ってそのまま取り入れています。

一応上記のコードを実行するとコンソールに

GET http://localhost:3000/question/?q_id=h28s002 404 (Not Found)

と表示されるので、「惜しいのかな?」とも考えています。
Axiosのドキュメントを参考にしたparamsの指定では、APIのURLと違ってしまうので、この点を上手く修正すれば、とりあえずAPIを上手く発火できそうな気がします。(もっとシンプルな方法がある気がしてならないけど…)

コードからもわかるとおり混乱中です。修正を続けていますが、具体的な修正案などがあればありがたいです。「リストから取得したq_idを、詳細情報取得用のAPIに組み込んで、その内容を表示する」ということがしたいです。
よろしくお願いします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

Vue.jsで一覧ページからidをキーとした詳細ページへ遷移したいという要件であれば、
Vue-Routerで対応するルート定義を作って、

#例 { path: '/question/:q_id', component: DetailXXX }

Vue-Router 動的ルートマッチング

router-linkのtoのparamsをリストの各要素のidなどにしてあげれば多分動くので行けると思います。

#例 <router-link :to="{ name: 'question', params: { q_id: question.q_id }}">IDが{{question.q_id}}の詳細へ</router-link>

Vue-Router router-link

※最後のAxiosの例で動的なHTMLかVueテンプレートを取得した後、そのHTMLをそのまま詳細ページとして当てはめて遷移するといった要件であるならば、もう少し複雑な事が必要かもしれません。

投稿2017/08/18 16:32

編集2017/08/18 16:38
aro10

総合スコア4106

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

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

退会済みユーザー

退会済みユーザー

2017/08/18 17:38

ありがとうございます。routerのpath設定が間違っていたようで、御指摘に沿って修正したところ、無事ページを遷移させることができました。本文に追記しておきます。 ページの遷移を完了させることができましたが、詳細情報を取得するためのAPI(http://localhost:3000/question/{q_id})が未発火なので、遷移先のページが空白のままです。 RootInstanceのcreated()で2012年の問題群を取得したように、ページ遷移したと同時にq_idを上記APIの{q_id}に代入して個別問題を取得したいと考えているのですが、どのような方法が考えられるでしょうか。動作こそしないものの、現在のDetailのコードなども早めに追記しようと思います。 もし解決案がありましたら、また御指摘を頂きたいと思います。よろしくお願いします。
aro10

2017/08/18 17:55 編集

詳細ページでページ情報を表示するのに必要なデータを取得するAPIを呼び出すタイミングは、mountedとwatchが良いかと思います。 ``` mouted:{ //コンポーネントが作成された際に発動 //APIからデータ取得し、ViewModelのdata等に適応 }, watch: { '$route' (to, from) { //同一コンポーネント間で遷移が発生した場合に発動 //APIからデータ取得し、ViewModelのdata等に適応 } } ``` [動的ルートマッチング](https://router.vuejs.org/ja/essentials/dynamic-matching.html) q_idの値は、this.$route.params.q_id のような形で取得できます [ルートオブジェクト](https://router.vuejs.org/ja/api/route-object.html)
退会済みユーザー

退会済みユーザー

2017/08/19 18:15

有用な情報をありがとうございます。 this.$route.params.q_idをAPIの{q_id}部分に組み込もうと、しばらく試行錯誤してみたのですが、少し苦戦しています。Vue Devtoolを見る限り、paramsはきちんとリストから読み込めているようです。 少しめちゃくちゃですが、現状のコードを再び追記しようと思います。具体的な修正案などがもしあれば、またアドバイスを頂ければなと思います。よろしくお願いします。
退会済みユーザー

退会済みユーザー

2017/08/20 03:17

質問文が少し長くなってしまったので、新しい質問として再度投稿し直そうと思います。丁寧に返答を下さりありがとうございました。ベストアンサーにさせて頂きます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問