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

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

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

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

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

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

Q&A

解決済

1回答

555閲覧

Vue.js3のx-templateを使った時に、親コンポーネントから子コンポーネントのメソッドを実行したい

mee12

総合スコア101

Vue.js

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

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

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

1グッド

0クリップ

投稿2022/02/22 03:51

編集2022/02/22 07:20

Vue.js3のx-templateを使った時に、親コンポーネントから子コンポーネントのメソッドを実行したいのですが、わからなくて困っています。
どなたか解決方法をご存知であれば教えて下さい。

javascript

1// index.js 2const app = Vue.createApp({ 3 data() { 4 return { 5 rowData: [] 6 }, 7 }, 8 9 methods: { 10 do () { 11 // this.$refs.child2がundefindなのでエラー 12 this.$refs.child2.send(); 13 }, 14 15 receive(data) { 16 this.rowData = data; 17 }, 18 } 19}); 20 21const childComponent2 = { 22 // 親のデータをpropsで受け取る 23 props: { 24 rowData: Array, 25 }, 26 27 // 子で再定義 28 data() { 29 return { 30 childRowData: this.rowData 31 } 32 }, 33 34 methods: { 35 // $emitで親のイベントを実行 36 send() { 37 this.$emit("receive", childRowData); 38 }, 39 }, 40 41 template: "#child-component2" 42}; 43 44app.component("child-component2", childComponent2); 45 46app.mount("#app");

html

1<!-- index.html --> 2<div id="app"> 3 <button type="button" v-on:click="do()"> 4</div> 5 6// Partial view (modal) 7// child-component2.html

html

1<!-- child-component2.html --> 2<script type="text/x-template" id="child-component2"> 3 <div> 4 custom component2★ 5 </div> 6</scirpt> 7 8<child-component2 ref="child2"></child-component2>

2022/02/22 16:17
タイトルと本文を修正しました。
親コンポーネントから子コンポーネントのメソッドを実行したいです。

次のそれぞれの宣言だとは思うのですが、
html : <child-component2 ref="child2"></child-component2>
javascript: this.$refs.child2.send();

luuguas👍を押しています

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

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

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

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

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

luuguas

2022/02/22 07:13

アクセスと言っていますが、具体的に何をしたいのですか。
mee12

2022/02/22 07:17

コメントありがとうございます。 わかりにくくてすみません。 親コンポーネントから子コンポーネントのメソッドを実行したいです。
guest

回答1

0

ベストアンサー

コンポーネント間の通信うんぬんの前に、基本的なことが全然できていません。コンポーネントを利用するために必要な下準備ができているか、ちゃんと確認しましょう。

コンポーネントの登録

html

1<!-- child-component2.html --> 2<child-component2 ref="child2"></child-component2>

作成した子コンポーネントは、テキトーな場所に配置しても動作しません。親コンポーネントの中に記述しましょう。

さらに、Vueに子コンポーネントの存在を知らせる必要があります。子コンポーネントは親コンポーネントより前で定義し、親コンポーネントにcomponentsプロパティを追加し、子コンポーネントを登録して下さい。

修正後:

html

1<!-- index.html --> 2<div id="app"> 3 <button type="button" v-on:click="do()"> 4 <!-- 親コンポーネント(#app)内に記述 --> 5 <child-component2 ref="child2"></child-component2> 6</div>

js

1//子コンポーネントを定義 2const childComponent2 = { 3 //... 4}; 5 6const app = Vue.createApp({ 7 data() { 8 return { 9 rowData: [] 10 }, 11 }, 12 //子コンポーネントを登録する 13 components: { 14 'child-component2': childComponent2, 15 }, 16 //... 17});

親→子のデータの伝達(Props down)

親のデータを子が受け取れるようにするには、v-bindを使って明示的に渡す必要があります。

修正後:

html

1<!-- index.html --> 2<div id="app"> 3 <button type="button" v-on:click="do()"> 4 <!-- v-bindで親のデータを子に渡す --> 5 <child-component2 ref="child2" v-bind:row-data="rowData"></child-component2> 6</div>

これで、子はpropsを使い親のデータを受け取ることができるようになります。

子→親にイベントを送信(Event up)

$emitで子から送信されたイベントは、v-onを使い親のメソッドと結びつけましょう。

修正後:

(コンポーネントの記述が長くなってきたので改行しました)

html

1<div id="app"> 2 <button type="button" v-on:click="do()"> 3 <!-- v-onでreceiveイベントを親のreceiveメソッドと結びつける --> 4 <child-component2 5 ref="child2" 6 v-bind:row-data="rowData" 7 v-on:receive="receive" 8 ></child-component2> 9</div>

その他の問題点

html

1<div id="app"> 2 <button type="button" v-on:click="do()"> <!-- (1)(4) --> 3 <child-component2 4 ref="child2" 5 v-bind:row-data="rowData" 6 v-on:receive="receive" 7 ></child-component2> 8</div>

js

1const childComponent2 = { 2 //... 3 methods: { 4 // $emitで親のイベントを実行 5 send() { 6 this.$emit("receive", childRowData); //(2) 7 }, 8 }, 9 //... 10}; 11 12const app = Vue.createApp({ 13 data() { 14 return { 15 rowData: [] 16 }, //(3) 17 }, 18 19 methods: { 20 do() { //(4) 21 this.$refs.child2.send(); 22 }, 23 //... 24 } 25});

(1) 閉じタグ</button>がありません。

(2) childRowDataではなく、this.childRowDataです。thisの付け忘れには十分注意しましょう。

(3) return文の後ろなので、,ではなく;です。

(4) do予約語なので、関数名として使うことはできません。別の名前に直しましょう。

(1),(4)修正後:

html

1<div id="app"> 2 <button type="button" v-on:click="send">Click</button> 3 <child-component2 4 ref="child2" 5 v-bind:row-data="rowData" 6 v-on:receive="receive" 7 ></child-component2> 8</div>

js

1const app = Vue.createApp({ 2 //... 3 methods: { 4 send() { 5 this.$refs.child2.send(); 6 }, 7 //... 8 } 9});

親→子のメソッドを実行

で、肝心の本題ですが、これまで指摘した箇所を修正してもらうと、おそらく正常に動作すると思います。ログを出力して確認してみて下さい。


土台となる知識が十分でないままやろうとしても上手くいきませんので、まずは基礎を再確認するところから始めましょう。

投稿2022/02/22 09:22

編集2022/02/22 13:44
luuguas

総合スコア492

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

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

mee12

2022/02/23 02:05 編集

丁寧に教えて頂きありがとうございます。とても勉強になりました。 無事に動作させることができました。 教えて頂いたことを知識の整理のためにまとめてみました。 ・コンポーネントの登録 コンポーネントは親コンポーネントの中に記述する。 親コンポーネントのcomponentsプロパティに子コンポーネントを登録する。 ・親→子のデータの伝達(Props down) v-bindを使って渡す キーの名前がよくわからなく、はまったのですが、 v-bindのキー名ってどうするんだろうと考えていましたが、 変数名の単語をハイフンでつないだ小文字のキーにしなければいけないことを見つけました。 ・子→親にイベントを送信(Event up) v-onを使って親と結びつける。 props, emitともに v-bind, v-onに任意のキーをつけるような使い方をしたことがなかったので、とても勉強になりました。 また、質問内容に誤記があり、(1)~(4)は初歩的な間違いでしたのでご迷惑をおかけし、すみませんでした。 ありがとうございました。
luuguas

2022/02/22 14:10

Events upじゃなくてEvent upでした…。修正しました。 属性名,変数名についてですが、 - HTMLに記述するコンポーネント名・属性名はケバブケース記法(例: my-app) - JavaScriptに記述する変数名・メソッド名はキャメルケース記法(例: myApp) - JavaScriptに記述するコンポーネント名はPascalケース記法(例: MyApp) を使用することが推奨されています。 v-bindについては、例えば、HTMLで子コンポーネントの属性に v-bind:row-data="~" と書くと、Vueがケバブケース(row-data)からキャメルケース(rowData)に変換し、子コンポーネント内のpropsに同名のプロパティがあれば、そこにデータを渡します。
mee12

2022/02/23 02:04

変数名の書き方についてよくわかりました。 ケバブケースとキャメルケースで相互に変換されるのですね。 ありがとうございます。 現在、Google Chromeブラウザコンソールにrenderに関する警告が出ており、 x-templateをレンダリングする場合、render等を書く必要があるのでしょうか? renderの書き方が調べてもよくわからなく、うまく表示できませんでした。 もしわかれば教えて頂きたいです。
luuguas

2022/02/23 02:19

今回の質問とは別の話になりますので、新しく質問を立ててください。そのほうが他の方からの回答も得られやすくなりますので。
mee12

2022/02/23 02:45

わかりました。別の質問を立てさせていただきます。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問