Vue.jsで資格の過去問題解説アプリを作成したいと考えています。
リストの問題がクリックされたとき、個別の詳細ページに遷移するシンプルなものです。
###リストページから詳細ページへの遷移は完了
リスト&検索用と詳細用2つのローカルDynamoDBテーブルを用意し、serverlessフレームワークのofflineプラグインを使って、localhost:3000にリスト用と詳細用の2つのAPIエンドポイントを実行しています。
先日は、リスト化された問題データから、詳細ページへの遷移ができないことを「[Vue.js]リストページのID要素を頼りに個別ページへ遷移させる方法」で質問して、ページを遷移させることができました。
(route.js)
javascript
1{ path: '/question/:q_id', component: QuestionDetail, name: 'detail'},
(QuestionList.vue)
javascript
1<template> 2 <div class="list"> 3 <h1>QuestionList page.</h1> 4 <div v-for="question in questions"> 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に、q_idが組み込めない
ページ遷移こそ成功しましたが、肝心の詳細情報が取得できずにいます。
リストページで取得したq_idを、詳細用APIの「http://localhost:3000/question/{q_id}」に埋め込んで実行するのに苦戦しています。
Vue devtoolを見ると、詳細ページはdataの$routeの中に確かに「question/2012q001」というparamsを含んでいます。前回の質問では、this.$route.params.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に組み込んで、その内容を表示する」ということがしたいです。
よろしくお願いします。
###詳細用APIの発火に成功!
aro10さんの指摘に沿って、コードを下記のように変更したところ、詳細用APIを無事動作させることができました。ローカルDynamodbのコンソールからもAPIの発火を確認し、Vue devtool側でもdataのquestionの中に詳細情報が格納されているのが確認できました。
javascript
1<template> 2 <div class="detail"> 3 <div v-if="question != null"> 4 <div>succeed</div> 5 {{ question }} 6 7 </div> 8 9 <div v-else> 10 <p>No Page.</p> 11 </div> 12 </div> 13</template> 14 15<script> 16 import axios from 'axios'; 17 18 export default { 19 name: 'detail', 20 data() { 21 return { 22 question: null 23 } 24 }, 25 mounted() { 26 this.getQuestion(this.q_id).then(question => this.question = question); 27 }, 28 beforeRouteUpdate(to, from ,next) { 29 this.getQuestion(to.params.q_id).then(question => this.question = question); 30 next(); 31 }, 32 methods: { 33 getQuestion(q_id) { 34 return axios.get(`http://localhost:3000/question/${this.$route.params.q_id}`, {}) 35 } 36 } 37 } 38</script>
###あと一歩!画面に各要素を表示させたい
ここまで質問して「いまさら?」と思われるかも知れませんが、詳細ページで取得したデータをどう画面に出力するかで少し悩んでいます。ちなみに詳細用のJSON構造は下記な感じです。
(questionDetail.json)
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 },
questionにデータがあるから、q_bodyを表示するときは、{{question.q_body}}で良かったんだっけ?と入力するも表示されず。とりあえず{{question}}とだけ入力し、JSON文字列がそのまま画面に出力されたのを確認したところで「あとどうするんだっけ」と悩んでいる現在です。
リストページで普通に使ってはいたものの、未だに混乱するポイントなので、有用そうなソースなど紹介して頂ければ幸いです。自己解決できるよう修正頑張ってみます。
###表示できた!
Vue devtoolの構造を見ながら表示部分を下記のように指定したところ、無事指定要素を画面に表示することができました。
javascript
1<template> 2 <div class="detail"> 3 <div v-if="question != null"> 4 <div>succeed</div> 5 <h2>問題本文</h2> 6 {{ question.data.Item.q_body }} 7 <h2>問題解説</h2> 8 {{ question.data.Item.q_desc }} 9 </div> 10 11 <div v-else> 12 <p>No Page.</p> 13 </div> 14 </div> 15</template>
{{question.data.Item.q_body}}という記述を短くする工夫などについては、どこかで見た記憶があるので、また継続的に修正を加えていきたいと思います。とりあえず、APIから各ページのデータを取得することができたので満足です。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2017/08/20 16:23
退会済みユーザー
2017/08/20 16:43