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

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

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

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

Q&A

解決済

1回答

207閲覧

【Vue.js】配列を返すcomputedの配列がエラーになる

fiveways

総合スコア1

Vue.js

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

0グッド

0クリップ

投稿2025/04/05 07:29

実現したいこと

配列を返すcomputedを配列にしたいです。

発生している問題・分からないこと

ソースコードのvalue2のように値を返すcomputedの配列は問題ありません。
list1のように配列を返すcomputedも問題ありません。
しかしlist2のように配列を返すcomputedを配列にすると期待通りに動作しません。

エラーメッセージ

error

1main.js:12 [Vue warn]: Unhandled error during execution of render function 2 at <Test onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< undefined > > 3 at <RouterView> 4 at <App> 5 6[Vue warn]: Unhandled error during execution of component update 7 at <RouterView> 8 at <App> 9 10chunk-U3LI7FBV.js?v=d72bdfcc:270 Uncaught (in promise) TypeError: Converting circular structure to JSON 11 --> starting at object with constructor 'ReactiveEffect' 12 | property 'deps' -> object with constructor 'Link' 13 --- property 'sub' closes the circle 14 at JSON.stringify (<anonymous>) 15 at toDisplayString (chunk-U3LI7FBV.js?v=d72bdfcc:270:196) 16 at Test.vue:24:47 17 at renderList (chunk-U3LI7FBV.js?v=d72bdfcc:5014:18) 18 at Proxy._sfc_render (Test.vue:1:1)

該当のソースコード

Vue.js

1<script setup> 2import { reactive, computed } from 'vue' 3 4const data = reactive({ 5 value: 0, 6 list: [0], 7}) 8const value1 = computed(() => data.value) 9const value2 = [computed(() => data.value)] 10const list1 = computed(() => data.list) 11const list2 = [computed(() => data.list)] 12</script> 13 14<template> 15 <button @click="data.value++; data.list[0]++">Click</button><br /> 16 {{ value1 }}<br /> 17 {{ value2[0] }}<br /> 18 {{ list1[0] }}<br /> 19 {{ list2[0][0] }}<br /><!-- エラーにはならないが表示されない --> 20 <ul> 21 <li v-for="v in list1">{{ v }}</li> 22 </ul> 23 <ul> 24 <li v-for="v in list2[0]">{{ v }}</li><!-- エラーになる --> 25 </ul> 26</template>

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

teratailで「Vue.js computed 配列」で検索しましたが同様の問題が見つかりませんでした。

補足

windows 11 pro 23H2
docker 27.3.1
docker desktop 4.36.0
node 23.11
vue 3.5.13

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

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

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

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

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

FKM

2025/04/08 08:28 編集

11行目のconst list2 = [computed(() => data.list)]をコメントアウトして出力変数を一旦消しても、まだ警告が出ますか?
fiveways

2025/04/08 11:22

11行目、19行目、24行目をコメントアウトすると警告は表示されません。 11行目と19行目についてはコメントアウトしなくても警告は表示されません。
guest

回答1

0

ベストアンサー

算出プロパティの役割を取り違えていなければ、list2のようなやり方で、オブジェクト代入ができないことがわかるはずです。

算出プロパティって結局何なのかと問われると、テンプレート上で何らかの処理が必要な変数の処理部分を、そこに隔離して置いているだけです。つまりイコールの関係が成り立ちます。

なのでvalue1はdata.valueと結びついていますし、プリミティブな値の0です。
value2も、その0を[0]とオブジェクトでラッピングしているだけなので問題ありません。
list1もdata.listの値と結びついており、その引数は[0]なので問題ありません。

一方、問題のlist2は[[0]]となった状態です。通常では、この方法だと[]に'[0]'という文字列が代入された状態になります。つまり現状、**list[0] の中身は '[0]' ということです。

証拠に{{ list2[0] }}としてみて、開発ツールで値を確認してみてください。おそらく文字列として[0]が表示されるはずです。

解決策

テンプレート上の[0]は文字列じゃなくて、値であることをJavaScriptに認識させてあげないといけません。その結果、以下のような記述になります。valueを付与し文字列から値を取得する方法、またはJavaScript的に['0']という連想配列が付与していると認識させて値を取得する方法、いずれも使用できるみたいです。

ちなみにv-forはプリミティブな値でもオブジェクトのいずれでもループ処理可能なので、マスタッシュ内に単純に出力する場合より、柔軟に変数が使えます。

<script setup> import { reactive, computed } from 'vue' const data = reactive({ value: 0, list: [1], //テストのために値を変更 }) const value1 = computed(() => data.value) const value2 = [computed(() => data.value)] const list1 = computed(() => data.list) const list2 = [computed(() => data.list)] </script> <template> <button @click="data.value++; data.list[0]++">Click</button><br /> {{ value1 }}<br /> {{ value2[0] }}<br /> {{ list1[0] }}<br /> {{ list2[0].value[0] }}<br /> <ul> <li v-for="v in list1">{{ v }}</li> </ul> <ul> <li v-for="v in list2[0]['0']">{{ v }}</li><!-- --> </ul> </template>

投稿2025/04/09 00:56

編集2025/04/09 01:30
FKM

総合スコア3660

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

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

fiveways

2025/04/09 03:25

回答ありがとうございます。 試したところ問題が解決しました! ベストアンサーに選ばせていただきました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問