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

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

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

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

Q&A

解決済

2回答

6014閲覧

Vue.js v-forのinput項目に対する監視をしたい(watch/compute)

snowtail

総合スコア13

Vue.js

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

0グッド

0クリップ

投稿2018/12/26 02:57

編集2018/12/26 03:24

vue.js初心者なので教えて下さい。

input項目を監視して、データ入力inputの度にデータが更新される(=methodが動く)ことを防ぎたいと考えております。

いろいろ調べて、lodashを使用・wach/createdを使用し、methodの呼び出しを遅らせればできるというところまでわかりました。(https://jsfiddle.net/j0s8ay1n/9/ にも同じソースがあります)

HTML

1<script src="https://unpkg.com/vue"></script> 2<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.10/lodash.min.js"></script> 3 4<div id="app"> 5 <input type="input" v-model="keyword"> 6 <pre>{{ $data }}</pre> 7</div>

vue

1new Vue({ 2 el: '#app', 3 data: { 4 keyword: null, 5 message: null 6 }, 7 watch: { 8 keyword: function (newKeyword, oldKeyword) { 9 this.message = "Waiting for you to stop typing...." 10 this.debouncedGetAnswer() 11 } 12 }, 13 created: function(){ 14 this.debouncedGetAnswer = _.debounce(this.listupdate, 1000) 15 }, 16 methods: { 17 listupdate(){ 18 console.log('更新します') 19 this.message = null 20 } 21 } 22});

同じ仕組みを、v-forでループしているinput項目にもやりたい、と思っております。
下記のソースにデータに対して、どのように、watch/createを記述することで、実現できるのでしょうか?
https://jsfiddle.net/9Laxj30z/ にも同じソースがあります)

HTML

1<script src="https://unpkg.com/vue"></script> 2 3<div id="app"> 4 <p v-for="list in lists"> 5 <input type="input" v-model="list.content" v-on:input="listupdate(list.id)"> 6 </p> 7 <pre>{{ $data }}</pre> 8</div>

vue

1new Vue({ 2 el: '#app', 3 data: { 4 lists: [ 5 {id: 1, content: "aaa"}, 6 {id: 2, content: "bbb"}, 7 {id: 3, content: "ccc"}, 8 {id: 4, content: "ddd"}, 9 ], 10 }, 11 methods: { 12 listupdate (listid) { 13 console.log(listid) 14 console.log('更新します') 15 } 16 } 17});

実現方法は、watchでなくてもなんでもよいと思っております。何卒よろしくお願い致します。

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

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

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

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

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

guest

回答2

0

ベストアンサー

watchにdeepオプションを付ければできると思います。

html

1<script src="https://unpkg.com/vue"></script> 2<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.10/lodash.min.js"></script> 3 4<div id="app"> 5 <p v-for="list in lists"> 6 <input type="input" v-model="list.content"> 7 </p> 8 <pre>{{ $data }}</pre> 9</div>

js

1new Vue({ 2 el: '#app', 3 data: { 4 lists: [ 5 {id: 1, content: "aaa"}, 6 {id: 2, content: "bbb"}, 7 {id: 3, content: "ccc"}, 8 {id: 4, content: "ddd"}, 9 ], 10 message: null 11 }, 12 watch: { 13 lists: { 14 handler: function (newKeyword, oldKeyword) { 15 this.message = "Waiting for you to stop typing...." 16 this.debouncedGetAnswer() 17 }, 18 deep: true 19 } 20 }, 21 created: function(){ 22 this.debouncedGetAnswer = _.debounce(this.listupdate, 1000) 23 }, 24 methods: { 25 listupdate (listid) { 26 console.log('更新します') 27 this.message = null 28 } 29 } 30});

投稿2018/12/26 06:09

編集2018/12/26 06:18
de9

総合スコア312

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

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

snowtail

2018/12/26 06:54

さっそくのご回答ありがとうございます!deepのオプションはじめて知りました。教えていただいたとおり、やってみたところ、入力中を待つことができました。 もう少し教えていただきたいのですが、どのinput項目(この例だと、id: 1~4)に入力されたのかをlistidとしてmethodに渡したいと思っています。このようなことは可能でしょうか?
de9

2018/12/26 07:38

なるほどそういうことでしたか。そうなるとdebounceでは難しいですね……(debouncedGetAnswerをリストの要素数だけ用意するとかならできそうですが) blurで問題なければshou6さんの方法をおすすめします。
snowtail

2018/12/26 07:56

再質問への回答も丁寧にありがとうございます。難しいということで理解しました。blurで、inputごとに、更新処理が走らなくなったので、いったんは大丈夫かと思っています。 しかし、カーソルをあてて、何も更新しなくても、カーソルを移動すると更新処理に飛んでしまうので、そのへんが改善ポイントかと思っているところです。
snowtail

2018/12/26 08:51 編集

ありがとうございます。changeでやってみたところ、意図どおり変更のときの動作でした!これで大丈夫だと思います。Eventについて確認してみようと思います。ありがとうございました!
guest

0

まず、debouncedGetAnswerは関数ですか?変数ですか?

データとして扱うならば、

vue

1data() { 2 return { 3 keyword: null, 4 message: null, 5 debouncedGetAnswer: - 6 } 7}

に追加してください。

関数ならば、methodsに追加する必要があります。

vue

1methods: { 2 debouncedGetAnswer() { 3 ~ 4 } 5}

入力中のみwaitingメッセージを出すならば下記の様な形でも出来ます。
focusが外れた段階でlistUpdate()が呼ばれます。

html

1# HTML側 2<div> 3 <input v-model="keyword" @input="message_show = true" @blur="listUpdate" /> 4 <p v-if="message_show">{{ message }}</p> 5</div>

vue

1<script> 2# 一部省略 3data() { 4 return { 5 keyword: null, 6 message_show: false, 7 message: "Waiting for you to stop typing...." 8 } 9}, 10watch: { 11 keyword(val) { 12 // valには新しい値が入ってくる 13 console.log(val) 14 } 15}, 16methods: { 17 listUpdate() { 18 this.message_show = false 19 console.log("更新します") 20 } 21} 22</script> 23

投稿2018/12/26 06:05

編集2018/12/26 06:05
shou6

総合スコア305

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

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

snowtail

2018/12/26 07:16

さっそくのご回答ありがとうございます!@blur知りませんでした。不勉強ですみません。 input入力を待つということがやりたいので、watchを使わずに@blurでもできそうです。ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問