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

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

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

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

Q&A

解決済

2回答

1309閲覧

Vue.jsで子コンポーネントのメソッドを使用したい

shun173

総合スコア4

Vue.js

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

0グッド

0クリップ

投稿2020/06/02 05:04

編集2020/06/02 06:14

前提・実現したいこと

Djangoでwebアプリを作成しており、template内でVue.jsを使用しています。
axiosでデータを取ってきた後、それに対応したコンポーネントのメソッドを使用したいです。

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

TypeError: Cannot read property 'isGood' of undefined at VueComponent.isGood (myscript.js:152) at Vue.<anonymous> (myscript.js:178)

該当のソースコード

html

1<div id="article"> 2 {% for article in articles %} 3 4 <article-good ref="{{ article.id }}" data-id="{{ article.id }}" data-count="{{ article.good_count }}"> 5 </article-good> 6 7 {% endfor %} 8</div>

javascript

1var articleGood = { 2 delimiters: ['[[ ', ']]'], 3 data: function () { 4 return { 5 gooded: false, 6 good_count: 0, 7 } 8 }, 9 mounted: function () { 10 var elm = this.$el; 11 var count = elm.getAttribute('data-count'); 12 var id = elm.getAttribute('data-id'); 13 this.good_count = Number(count); 14 }, 15 template: '<div><i :class="heart" @click="changeGood"></i><span>[[ good_count ]]</span></div>', 16 computed: { 17 heart: function () { 18 return { 19 fas: this.gooded, 20 far: !this.gooded, 21 'fa-heart': true, 22 'fa-blue': true 23 } 24 } 25 }, 26 methods: { 27 //goodボタンが押された時の切り替え 28 changeGood: function () { 29 if (this.gooded) { 30 this.good_count -= 1; 31 } else { 32 this.good_count += 1; 33 } 34 this.gooded = !this.gooded; 35 }, 36 //既にgoodされていたときはボタンをオンにする 37 isGood: function () { 38 this.$refs[id].isGood(); //(← 152行目) 39 this.gooded = true; 40 } 41 } 42} 43 44new Vue({ 45 el: '#article', 46 delimiters: ['[[ ', ']]'], 47 components: { 48 'article-good': articleGood, 49 }, 50 mounted: function () { 51 axios.get('/snsapp/gooded_articles/') 52 .then(function (response) { 53 var article_ids = response.data.article_ids; 54 console.log(article_ids); //(1) 55 for (var i = 0; i < article_ids.length; i++) { 56 id = String(article_ids[i]); 57 console.log(id); //(2) 58 console.log(this.$refs); //(3) 59 console.log(this.$refs[id]); //(4) 60 this.$refs[id].isGood(); //(5) (← 178行目) 61 }; 62 console.log(this.gooded_articles); 63 }.bind(this)) 64 .catch(function (error) { 65 console.log(error); 66 }.bind(this)); 67 }, 68});

試したこと

#######consoleの結果

(1) : (2) [1, 3] (2) : 1 (3) : {1: VueComponent, 2: VueComponent, 3: VueComponent, 6: VueComponent, 7: VueComponent, 8: VueComponent, 9: VueComponent} (4) : VueComponent (5) : TypeError: Cannot read property 'isGood' of undefined at VueComponent.isGood (myscript.js:152) at Vue.<anonymous> (myscript.js:178)

Vue.js公式ガイド/特別な問題に対処するを参考にしてref属性を設置して試してみたのですが上手くいきません。
また、公式ガイドを読んでもどのようにメソッド呼び出しているのかいまいちよく分かりません。

”公式ガイド一部抜粋”

methods: {
// 親からインプット要素をフォーカスするために使われる
focus: function () {
this.$refs.input.focus()
}
}

これはfocusメソッドが自分自身を呼び出している?

必要であればDjango側のコードも載せます。
よろしくお願いします。

###補足
お二方の回答でご指摘いただいた箇所を修正したらコンポーネントは呼び出せたようですが、メソッドを使おうとするとエラーが出ます。
エラー内容は上記の通りです。
よろしくお願いします。

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

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

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

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

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

guest

回答2

0

ベストアンサー

JavaScript

1 for (var i = 0; i < article_ids.length; i++) { 2 id = String(article_ids[i]); 3 console.log(id); //(2) 4 console.log(this.$refs); //(3) 5 console.log(this.$refs.id); //(4) 6 this.$refs.id.isGood(); //(5) 7 };

console.log(this.$refs.id); //(4)のidってもしかしてid = String(article_ids[i]);の値を利用したいってことであれば
console.log(this.$refs[id]); //(4)こうするのがただしいですよ(5)も同様

投稿2020/06/02 05:42

rururu3

総合スコア5545

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

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

shun173

2020/06/02 06:24

ご指摘いただいた箇所を修正しました。 よろしければご回答お願いします。
rururu3

2020/06/02 06:30

処理まで追っかける気ないけど //既にgoodされていたときはボタンをオンにする isGood: function () { this.$refs.id.isGood(); this.gooded = true; } の部分のisGood呼び出しでエラー出てますよ
shun173

2020/06/02 06:51

返信ありがとうございます。 this.$refs.id.isGood(); → this.$refs[id].isGood(); は修正しました。 エラーが出ているのは分かるのですが、その原因が分からないです。 この部分は公式ガイドを参考にしたのですが、そもそも関数の中で自分自身を呼び出している?のがよくわからないです。 初歩的な質問ですみません。 ご回答いただけると嬉しいです。
rururu3

2020/06/02 06:58

this.$refs.id ではだめで this.$refs[id] なら大丈夫っていう理由がわからないってことでいい?
shun173

2020/06/02 07:20

返信ありがとうございます。 いえそうではなく、this.$refs[id].isGood() と修正したうえで出るエラーの原因が分かりません。 親のVueから子のisGoodメソッドを使用したいのですが、 TypeError: Cannot read property 'isGood' of undefined at VueComponent.isGood (myscript.js:152) at Vue.<anonymous> (myscript.js:178) このようなエラーが出ます。 this.$refs[id]と記述する理由も正直よくわかっていないのですが(笑)、連想配列からキーで指定するというイメージで納得しています。
rururu3

2020/06/02 07:37

this.$refs[id].isGood(); //(← 152行目) ここでのthisはvueコンポーネントオブジェクトになるのでthis.$refsには自身の子に関するrefの参照が入ってます なのでアクセスできないのと、152行目のは自身のisGood呼び出すって感じなのだからthis.isGood()でいいのでは?
shun173

2020/06/02 08:00

返信ありがとうございます。 そもそも152行目が丸ごと不要でした笑 長々とお付き合いいただき大変ありがとうございました!
guest

0

createdの時点ではまだthis.$refsが正しくセットされていないため、うまく動作していないのだと思います。
代わりにmountedを利用してみてください。

サンプル

html

1<!DOCTYPE html> 2<html> 3<head> 4<meta charset="utf-8"> 5<script src="https://cdn.jsdelivr.net/npm/vue"></script> 6</head> 7<body> 8 9<div id="vue-app"> 10 <child-component ref="child" /> 11</div> 12 13<script> 14var childComponent = { 15 data: function() { return {"message": ""}; }, 16 template : '<span>{{ message }}</span>', 17 methods : { "hoge": function() { this.message = "child method called!"; } }, 18}; 19 20new Vue({ 21 el: '#vue-app', 22 components: { 23 'child-component': childComponent, 24 }, 25 mounted: function() { 26 this.$refs.child.hoge(); 27 } 28}) 29</script> 30 31</body> 32</html>

投稿2020/06/02 05:21

ku__ra__ge

総合スコア4524

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

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

shun173

2020/06/02 06:24

ご指摘いただいた箇所を修正しました。 よろしければご回答お願いします。
ku__ra__ge

2020/06/02 07:42

修正を行ったことで「Vue.jsで子コンポーネントのメソッドを使用したい」という目的は既に達成されているように思えます。 追記されたエラーは子コンポーネントのメソッド呼び出された結果、そのメソッドの実行中に発生しているのではないでしょうか? isGood: function () { this.$refs[id].isGood(); //(← 152行目) this.gooded = true; } の「(← 152行目)」で呼び出された子コンポーネントのisGoodメソッド内でさらに別のisGoodを呼び出そうとしているように見えますが、この行は不要に思えます。 質問者さんは、何を行う意図でこの行を書いているのでしょうか?
shun173

2020/06/02 08:00

返信ありがとうございます。 おっしゃる通りこの行は不要だったようで、これを丸ごと削除したところ上手くいきました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問