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

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

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

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

Q&A

解決済

1回答

1872閲覧

Vueで配列をDOM作成前に読み込みたい

landy77

総合スコア1614

Vue.js

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

1グッド

1クリップ

投稿2020/02/12 14:44

Vue.jsでテンプレート内で配列を使用しています。
ものすごく省略すると下記の様な感じです。
createdなりmountedなりでaxiosで読み込んでいるので最終的にはちゃんと表示されますがConsoleには「Error in render: "TypeError: Cannot read property 'name' of undefined"」とエラーが表示されます。

そこで同期処理としてasync、awaitを使えば良いのか?と思いまして下記のように書いてみました。

js

1<template> 2 <div> 3 <div>{{lists[0].name}}</div> 4 <div>{{lists[1].name}}</div> 5 <div>{{lists[2].name}}</div> 6 </div> 7</template> 8 9<script> 10import axios from 'axios' 11export default { 12 data(){ 13 return{ 14 lists:[] 15 } 16 }, 17 created(){ 18 const main = async () => { 19 var res = await axios.get("http://localhost/api/getLists.php"); 20 console.log(res); 21 this.lists = res.data.lists; 22 } 23 24 main(); 25 26 console.log(this.lists); 27 } 28} 29</script>

先に書いたとおり画面上にはaxiosも実行されているので最終的にはちゃんと表示されています。

期待している動作はcreatedでmain()が実行されてaxiosの受取を待機することで(同期することで)this.listsに配列が代入されることでテンプレートのエラーを表示したくないのです。
(data()内でlists配列の内容を空でちゃんを入れればエラーが出ないのは承知しています)

しかし実際はConsoleを見る限りCannot read property 'name'・・エラーの後にconsole.log(this.lists);が実行されてその後console.log(res);が実行されているように見えています。

期待している動作をさせるにはどう書いたらよいでしょうか?

bz5adgjmptw0👍を押しています

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

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

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

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

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

guest

回答1

0

ベストアンサー

先にテンプレートが評価されていることが原因です。
「lists[0].name」などを表示しようにも対象のデータがないためエラーとなっています。

データが注入されてから表示するように調整するか、v-forで書き出すようにすると良いと思います。
v-forのほうがデータの変更に強いのでおすすめです。

html

1<div v-if="lists.length"> 2 <div>{{lists[0].name}}</div> 3 <div>{{lists[1].name}}</div> 4 <div>{{lists[2].name}}</div> 5</div> 6<!-- または --> 7<div v-for="(item, index) in lists" :key="index"> 8 {{ item.name }} 9</div> 10

投稿2020/02/13 04:26

nt4c

総合スコア768

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

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

landy77

2020/02/13 05:08

対処法が若干面倒ですが納得できました! なるほど、テンプレートとして作成した場合は何が何でも先に評価されてしまうんですね。 createdでもbeforecreatedでも先にテンプレートのエラーが出てしまうので何らかの解決があっても良いような気はするんですけどね・・・・
nt4c

2020/02/13 05:19

Vueのライフサイクルをcreatedなどに登録した非同期処理が完了するまで次のステップに進めないでほしいというお考えですよね? 数年前に公式でも似たようなことが議論されていますが、ロジックを大幅に変える必要があり破壊的な修正となるため採用されませんでしたね。 https://github.com/vuejs/vue/issues/7209 どうしてもということであればNuxtなどを採用してサーバーサイドレンダリングするしかないかなと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問