0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Vue.jsで親から子孫コンポーネントにデータを渡せない

Last updated at Posted at 2020-04-20

Vue.jsを勉強初めて数日。
コンポーネント?
なるほど、関数みたいに使えて便利なんですね。
ローカル登録?まぁ理屈はわかる。
と思ってやって見たら、、、
全然データが渡せない。
どうすればいいか困ってましたが、なんとかできたのでメモしときます。
完全にメモです。

グローバルコンポーネント

test.html
<div id="pre">
    <my-component-name></my-component-name>
</div>

「Vue.component」を使ってグローバル登録する。

test.js
Vue.component('my-component-name', { 
    template: 
        `<button class="demo">追加オーダー</button>`
})

new Vue({
    el: '#pre'
})

これでHTML内の自作タブが置き換わります。
ただ、グローバルなので、どこでも置き換わってしまうし、いちいち読込みが発生する。
公式でも理想的じゃないとのこと。

多くの場合、グローバル登録は理想的ではありません。例えば Webpack のようなビルドシステムを利用しているときに、グローバルに登録した全てのコンポーネントは、たとえ使用しなくなっても、依然として最終ビルドに含まれてしまうことでしょう。これは、ユーザがダウンロードしなくてはならない JavaScript のファイルサイズを不要に増加させてしまいます。

ローカルコンポーネント

HTMLがこんな感じだとする。

test.html
<div id="pre">
    <my-component-name></my-component-name>
</div>

HTML側で何のデータを利用するか、名前を付けてバインドさせとく。
(下の図はVueインスタンスdata内のechoPatientを「check1」, cardiacEchosを「check2」と名前付けてる)

test.html
<div id="pre">    
    <my-component-name v-bind:check1="echoPatient" v-bind:check2="cardiacEchos"></my-component-name>
</div>
<!-- それぞれ[check1][check2]という名前で子コンポーネントに渡す -->

パーツを別で定義しておく。(下の図では定数teleDataで定義)
送りつけられたデータを子コンポーネントで利用するときは、propsオプションを記述し、何を受け取るか記述。
受け取る時、バリデーションを付けれる。
Vueインスタンスのcomponentsオブジェクトを使って、どこに何を当てはめるか記述する。
createdフックやmethodオブジェクト内で作成したデータを子コンポーネントに渡すときとか、
データを渡す必要がある時は、dataオブジェクトがちょっと特殊な書き方になる。

test.js
const teleData = {
    props: {         //何を受け取るか記述
        check1: {
            type: Object,
            required: true,
        },
        check2: {
            type: Number,
            required: true,
        },
    },
    template:
        `<p>Patient name : {{ check1.name }}</p>
         <p>CardiacEcho : {{ check2 }}</p>`
}

new Vue({
    el: '#pre',
    components: 
        "my-component-name": teleData,          //どこに何を当てはめるか記述
    data: function() {      //ここの書き方が変わる
        return {
            echoPatient: { ...(オブジェクト)... },
            cardiacEcho: 10,
        };
    };
})

孫に渡したい

もう一度HTMLを記述しておくと、こう。

test.html
<div id="pre">    
    <my-component-name v-bind:check1="echoPatient" v-vind:check2="cardiacEchos"></my-component-name>
</div>
<!-- それぞれ[check1][check2]という名前で子コンポーネントに渡す -->

「子が受け取ったものを渡す」というイメージで記述。
孫にあたるコンポーネントも変数として定義する。

test.js
const patientData = {    //孫にあたるコンポーネント1
    props: {          //何を受け取るか記述
        first: {
            type: Object,
            required: true,
        },
    },
    template:
        `<p>patient name : {{ first.name }}</p>`
}

const patientScan = {    //孫にあたるコンポーネント2
    props: {          //何を受け取るか記述
        second: {
            type: Number,
            required: true,
        },
    },
    template:
        `<p>echo scan : {{ second }}</p>`
}

const teleData = {    //子コンポーネント ここで2つデータを受け取ってる
    props: {          //何を受け取るか記述
        check1: {
            type: Object,
            required: true,
        },
        check2: {
            type: Number,
            required: true,
        },
    },
    components: {            //どこに何を当てはめるか、再度記述
        'patient-data' : patientData,    //この変数が孫にあたる。別で定義
        'patient-scan' : patientScan,    //これも別で定義
    template:       //孫に渡すデータをバインドしとく ルート要素は1つじゃないとダメなので、divで囲む
        `<div>
             <patient-data v-bind:first="check1"></patient-data>    
             <patient-scan v-bind:second="check2"></patient-scan>
         </div>`
}

new Vue({
    el: '#pre',
    components: 
        "my-component-name": teleData,      //どこに何を当てはめるか記述
    data: function() {   //ここの書き方が変わってる
        return {
            echoPatient: {
                id: 1,
                name: hoge,
                ...
            },
            cardiacEchos: 10,
        };
    };
})

正直あってるかは分かりませんし、もっと上手いやり方や正解があるとは思いますが、
一応これで動いたので残しておきます。
ダメな所とかありましたらご指摘いただけたら嬉しいです。

こちらのページ様を思いっきり参考にさせていただきました。
分かりやすくて非常に勉強になりました。
公式ページ
Vue.jsをシンプルに理解しよう

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?