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

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

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

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

Q&A

解決済

1回答

5137閲覧

Vue.jsでv-for中のデータ更新

jabasklipt

総合スコア13

Vue.js

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

0グッド

0クリップ

投稿2018/11/24 06:06

前提・実現したいこと

Vueのバージョン : 2.9.6
したいこと : v-for中にデータを更新したい。

よろしくおねがいします。

発生している問題・エラーメッセージ

Error compiling template:

該当のソースコード

JS

1var hoge = new Vue({ 2 el:'#wrap', 3 data:{ 4 info_data : [ { "id": 1,"num": "10", }, { "id": 2,"num": "20", }, { "id": 3,"num": "30", } ], 5 last_num : '0', 6 } 7});

HTML

1 <article :key="val.id" v-for='val in info_data'> 2 <div v-if="val.num != last_num"> 3 <span >{{val.num}}</span> 4 <input v-model="last_num" v-bind:value="val.num">//ここでlast_numを更新したい 5 //{{last_num = val.num}}とすると期待した動作をしますがエラーがでます 6 [Vue warn]: You may have an infinite update loop in a component render function. 7 </div> 8 </article>

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

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

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

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

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

guest

回答1

0

ベストアンサー

v-modelは、デフォルトではvalueinputイベントで更新するための省略構文(シュガーシンタックス)です。
jabaskliptさんの場合は、別途v-bind:valueをしているのでおかしくなっているのだと思います(エラーにいたる内部の詳細な動きは把握していません)。

上記の通りv-modelはただのシュガーシンタックスなので、自前で更新をかければ解決します。

HTML

1<div id="wrap"> 2 <article :key="val.id" v-for='val in info_data'> 3 <div v-if="val.num != last_num"> 4 <span >{{val.num}}</span> 5 <input :value="val.num" @input="updateLastNum(val.num)"> 6 </div> 7 </article> 8</div>

JavaScript

1var hoge = new Vue({ 2 el:'#wrap', 3 data:{ 4 info_data : [ { "id": 1,"num": "10", }, { "id": 2,"num": "20", }, { "id": 3,"num": "30", } ], 5 last_num : '0', 6 }, 7 methods: { 8 updateLastNum(num) { 9 this.last_num = num; 10 } 11 } 12});

v-modelを、valueおよびinputイベント以外に使用したい場合こちらを参照してください。

追記(2018/11/24)

質問の意図が確定したので、改めて回答します。
結論から言うと、jabaskliptさんがやろうとしていることは、質問に記載されたやり方だとできません。

テンプレートの中でデータを変更するのではなく、
テンプレートで使用する前にデータを整形しておく必要があります。
以下の例では、2つ目の10(id4の方)は表示されていません。

サンプル

補足

Vue.jsでは、あるデータが変更された場合、即座にレンダリング(DOMに反映)されません。
同じタイミングで起きるデータ変更すべてを一旦保存しておきます。
すべてのデータ変更が検知されたあとにレンダリング(DOMに反映)されます。
そのため、あるデータをレンダリングの最中に変更しても、そのレンダリング中に再利用することはできません。
次の更新に持ち越されるからです。
詳しくはこちらを参照してください。

投稿2018/11/24 07:53

編集2018/11/24 10:50
NozomuIkuta

総合スコア1260

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

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

jabasklipt

2018/11/24 09:01

回答ありがとうございます! ただ動かしてみると、他にどこかが悪さしているのかinputイベントが発火しないです。(エラーも無し)
jabasklipt

2018/11/24 09:21

すみません、質問の仕方が悪かったです。 追記した{{last_num}}がループ毎に10,20,30と表示されて欲しいという内容でした。 https://jsfiddle.net/7y3hr2fo/
NozomuIkuta

2018/11/24 09:28

`last_num`は"0"ですので、変更しない限りずっと"0"のままですが、「{{last_num}}がループ毎に10,20,30と表示されて欲しい」とはどういった意味ですか?
jabasklipt

2018/11/24 09:32

このv-forは3回ループすると思うのですが、 1ループする度にlast_numの値をval.numの値に変更したいという意味です。
NozomuIkuta

2018/11/24 09:37

3回目のループでは`val.num`は"30"ですから、`last_num`も最終的には"30"になっていて欲しいということですね。 つまり`last_num`を`info_data`配列の最後のオブジェクトに基づいて設定したいということですか?
jabasklipt

2018/11/24 09:42

>`last_num`も最終的には"30"になっていて欲しい そうです。 >`last_num`を`info_data`配列の最後のオブジェクトに基づいて設定したい いえ、<div v-if="val.num != last_num">の部分で1つ前のループのval.numと今回のループのval.numが同じ値だった時は<span >{{val.num}}</span>を表示しないという分岐を行いたいです。
NozomuIkuta

2018/11/24 09:51

> いえ、<div v-if="val.num != last_num">の部分で1つ前のループのval.numと今回のループのval.numが同じ値だった時は<span >{{val.num}}</span>を表示しないという分岐を行いたいです。 もし`num`が 10, 10, 20, 30 だとしたら、2つ目の10を表示したくない、つまり、画面に表示される数字に重複がないようにしたいということですか?
jabasklipt

2018/11/24 11:02

詳しくご回答いただいてありがとうございます! そもそも仕組みを理解していなかったという事ですね。勉強になりました!
NozomuIkuta

2018/11/24 11:05

解決したようでよかったです。 Vue.jsの公式サイトは、日本語版もあり、説明も丁寧なので、いつか通読されることをおすすめします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問