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

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

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

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

235閲覧

【Vue.js】dataの配列にmethodsの関数式を代入したい

lookman

総合スコア4

Vue.js

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2023/02/07 08:04

実現したいこと

<input type="checkbox">で選択された要素に紐づく関数のみを、実行したいです。

ソースコード

次のような、「変換」ボタンを押したときにcheckboxで選択された関数のみを実行するコードがあります。

html

1<div id="main"> 2 <ul> 3 <template v-for="value in options"> 4 <li> 5 <label> 6 <input type="checkbox" v-model:checked="value.checked"> 7 <span>{{ value.title }}</span> 8 </label> 9 </li> 10 </template> 11 </ul> 12 <button v-on:click="convert()">変換</button> 13</div>

JavaScript

1const vm = new Vue({ 2 el: "#main", 3 data: { 4 options: [ 5 {title: "A", checked: true, convert: this.convertA}, 6 {title: "B", checked: true, convert: this.convertB}, 7 {title: "C", checked: true, convert: this.convertC} 8 ], 9 }, 10 methods: { 11 convert() { 12 this.$data.options.filter(element => { 13 return element.checked; 14 15 }).forEach(element => { 16 element.convert(); 17 }); 18 }, 19 convertA() { 20 console.log("ここはAです。"); 21 }, 22 convertB() { 23 console.log("ここはBです。"); 24 }, 25 convertC() { 26 console.log("ここはCです。"); 27 }, 28 }, 29});

ここでは説明のために簡略化していますが、"convertA~C"関数は本来、まったく異なる挙動をします。

発生している問題

16行目のelement.convertで「is not a functionエラー」が生じて、関数が実行できません。開発者ツールで確認するとelement.convert = undefinedでした。おそらくdataを定義するときに、関数式が代入されていないのだと思います。

一方で、convert関数内でconsole.log(this.convertA)を確認したところ、ƒ () {...}という望んだ結果が得られています。

知りたいこと

dataに、methodsで定義した関数(convertAなど)を代入するには、どのようにコードを変更すればよいでしょうか?

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

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

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

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

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

guest

回答2

0

自己解決

コメントを参考にして、ソースを次のように修正しました。

JavaScript

1const vm = new Vue({ 2 el: "#main", 3 data: { 4 options: [], 5 }, 6 mounted: function(){ 7 this.$data.options.push(...[ 8 {title: "A", checked: true, convert: this.convertA}, 9 {title: "B", checked: true, convert: this.convertB}, 10 {title: "C", checked: true, convert: this.convertC} 11 ]); 12 }, 13 ... 14});

Vue.jsのライフサイクルに基づき、$elプロパティはmountedまで利用できません。よって、mounted関数内で、optionsに値をバインドしました。

投稿2023/02/07 10:07

lookman

総合スコア4

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

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

0

Vue.jsのライフサイクルをもとに考えると、dataの初期化をおこなうタイミングでは、まだmethods含む種々のデータが揃っていないのだと思います。(あくまで私の推測ですが)

そのため、this.convertAを代入しようとしても、肝心のデータがまだ用意できていないため、代わりにundefinedが代入されているのでしょう。

要は、データの初期化が終わった後であれば、this.convertAがちゃんと用意されているので、正しく代入できるということです。

そこで、データの初期化が終わった直後に呼び出されるcreatedフックを使います。詳しく説明すると、data内のオブジェクトには仮の関数(()=>{}でよいでしょう)を代入しておいて、後からcreated()内でthis.convertAを代入します。

js

1const vm = new Vue({ 2 el: "#main", 3 data: { 4 options: [ 5 //convertには仮の関数を代入しておく 6 {title: "A", checked: true, convert: ()=>{}}, 7 {title: "B", checked: true, convert: ()=>{}}, 8 {title: "C", checked: true, convert: ()=>{}} 9 ], 10 }, 11 created() { 12 //データが用意された後で改めて代入 13 this.options[0].convert=this.convertA; 14 this.options[1].convert=this.convertB; 15 this.options[2].convert=this.convertC; 16 }, 17 //... 18});

ライフサイクルについて、詳しくは下記のサイトを読んでみてください。

投稿2023/02/07 09:23

luuguas

総合スコア492

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

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

lookman

2023/02/07 10:10

@luuguas さん ライフサイクルについてを見て、ソースを変更して自己解決しました。コメントありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問