【Vue(Nuxt)】v-ifとpropsで子コンポーネントの表示制御を行う

プログラミング学習

v-ifやifで親コンポーネントからで子コンポーネントの表示制御を行う方法です。覚書も多少かねています。

v-ifとpropsで子コンポーネントの表示制御を行う(方法1)

子コンポーネント

まず、子コンポーネントをv-ifで切り分け、親コンポーネントとデータのやりとりをするためpropsを用意しましょう、

    <b-container fluid="xl">
      <b-row v-if="showChildA" class="my-2 py-2">
        <b-col cols="12">表示A</b-col>
      </b-row>
      <b-row v-if="showChildB" class="my-2 py-2">
        <b-col cols="12">表示B</b-col>
      </b-row>
      <b-row v-if="showChildC" class="my-2 py-2">
        <b-col cols="12">表示C</b-col>
      </b-row>
    </b-container>

htmlはbootstrapvueを使っているため、適時書き換えてください。

  props: {
    showChildA: {
      type: Boolean,
      default: true
    },
    showChildB: {
      type: Boolean,
      default: true
    },
    showChildC: {
      type: Boolean,
      default: true
    }
  },

defaultをfalseにすると、その部分が非表示になります。

親コンポーネント

次に親コンポーネントです。

      <Childcomponents
        :show-child-a="showA"
        :show-child-b="showB"
        :show-child-c="showC"
      />

ハイフンを使いなさいとwaringででたため命名はハイフンにしました。ケバフケースにします。

falseにしたものだけ消えます。

import Childcomponents from '~/components/Childcomponents.vue'

export default {
  components: {
    Childcomponents
  },
  data() {
    return {
      // 子コンポーネントの表示管理
      showA: false,
      showB: true,
      showC: false
    }
  }
}

propsはこちらの記事がわかりやすいです。

【Nuxt.js】props基礎編:コンポーネントに自由にデータを渡そう | aLiz Nuxt
前置き componentの内容を、ページによって変えたいってこと、ありますよね?親によって文字を変えたり、b

あとはUdemyなどで勉強しましょう。

【複数】親ページの2ヵ所から1つのファイルにある違う子コンポーネントを読み込む

レイアウトや他のコードの都合上、コンポーネントを読み込む箇所が2箇所になってしまう場合です。
子コンポーネンを以下にするだけです。親側は各々falseに設定するだけです。

<div v-if="this.$route.name === 'PageName' && this.$route.name ===  'partsA '">
</div>
<div v-if="this.$route.name === 'PageName' && this.$route.name ===  'partsB '">
</div>

propsは配列や関数を渡す場合は注意

型だけの場合はこう。

props: {
  propArray: Array
},

中には型を指定していないコードもありますが、基本型は指定することが多い気がします。defaultも指定しないとeslintのエラーがでるため、、結局、typeとdefaultの両方は指定することが個人的に多いですね。

アロー関数なので配列や関数を渡す場合は若干注意が必要です。

default: () => {}

ボタンclick時にpropでデータをゲットする

違うところは、子コンポーネントはcomputedで監視します。

スポンサーリンク

emitの使い方

propsとemitの違い

コンポーネントの表示制御だけならpropsでOKです。コンポーネントからデータをセットする場合はemitが必要です。

初心者向けemitの使い方

子から親に渡すものなので子コンポーネント(componetsフォルダのファイル)に書きます。厳密には親コンポーネントのイベントを発火できるもの。

this.$emit('childEditFlag', this.isEditFlag)

ボタンクリック時に渡すみたいな使い方が多い気がします。

  methods: {
    send() {
      this.$emit('childEditFlag', this.isEditFlag)
    }
  }

受け取り側はこう書きます。@はv-onです。htmlで完結する場合、代入する形です。

@childEditFlag="checkEditFlag = $event"

Javascriptに渡す場合は次のようになります。

<ChildComponent @childEditFlag="checkEditFlag"/>
methods: {
  checkEditFlag(flag) {
      console.log('checkEditFlag', flag)
  }
}

clickイベントのような形で引数なしで渡すケース

フラグ程度であれば実際は引数を渡す必要はないでしょう。子で発火させて値を渡すのは親側のみで完結します。modalウィンドウを閉じる場合なんかに利用されます。

  methods: {
    closeModal() {
      this.$emit('close')
    }
  }
<ChildComponent @close="modal('mes')"/>

初心者時代、udemyの「超Vue JS 2 入門 完全パック – もう他の教材は買わなくてOK! (Vue Router, Vuex含む)」を参考にさせてもらいました。

スポンサーリンク

propsのエラー

prop must be a string

prop must be a string

コピペでうっかりエラー。Stringになっていてもdefaultがfalseになっていたためエラー。

props: {
    uid: {
        type: String,
        default: false
    }
},

props: {
    uid: {
        type: String,
        default: ''
    }
},
スポンサーリンク

親コンポーネントから子コンポーネント内のメソッドを発火(refs)

propsやemitの他にrefsという手法があります。
次のように親コンポーネントに書くと、簡単に子コンポーネントのcancel() を呼び出せます。

<Child ref="child" />
this.$refs.child.cancel()

$refsの他に、$parent、$rootもあります。

propsはまどろっこしく感じてしまうところもありますが、$refsのいいところはわかりやすいです。ただ、こんなツイートが。

詳しくは調べていないのですが、$refsを使うと動作がもっさりする気がします(ただ、デプロイするともっさりしませんね。。)。

stackoverflowでも議論されていますが、methodの呼び出しは意見が割れているようです。

スポンサーリンク

親のページ名でif文の切り分け(方法2)

値のやりとりがない場合、親のページ名で子コンポーネントを切り分けることもできます。

htmlとjsは各々次のとおりです。こちらは記述量が少なく簡単です。実は表示と非表示の制御だけならこっちでいいかも。

<div v-if="this.$route.name === 'parentPagename'">
親ページに表示するもの。
</div>
<div v-else>
その他のページに表示するもの。
</div>
if(this.$route.name === 'parentPagename'){
  console.log('this.$route.name(ページ名)', this.$route.name)
}

動的なページ対応はthis.$route.name.includes(‘user’)

よくありますが、userページが増えていくような動的なページがあったとしましょう。

フォルダ構造はuser/_userみたいな感じです。その場合、次の対応でいけるっぽいです。

Twitterでもたまに簡単なことがつぶやいています。

コンポーネント設計の記事参考

よさそうな記事があったので紹介だけ。

nuxt.jsのmixinとは

mixinとはVueのデフォの機能です。VueComponentのコードを再利用する際に共通化するのがmixin。クラスを継承するような感じです。用途としては、たとえばComponentにloading.vueを用意し、ページのloading画面を共通化します。

mixinを使わなくても、injectなどの代替手段もあります。

mixiinの使い方下記の記事が参考になりました。ありがとうございます。

補足すると、data、computed、watch、created、methodsなどを共通化できます。

pagesとpluginのmixinに同じデータがあった場合、pagesのデータにマージされるので注意してください。

処理的にはmixiin、pagesの順番に呼ばれます。

注意事項としては下記があります。

俺がやらかしたVue mixinのアンチパターンから学ぶmixinの使い方と代替案
VueComponentのリファクタリングや構造化をしようと思ったとき、選択肢の一つとしてmixinが考えられますよね。しかし振り返るとうまく実装できていないケースがちらほらありました。なぜそうなってしまったかと、それを踏まえての適切なmixinの使い方または代替案についてまとめてみました。mixin実装時のご参...

ミックスインは継承ツリーを持たないため、オブジェクト指向言語の継承と違います。

mixinかコンポーネントかどちらかと言われれば、基本コンポーネント。やむ得ない事情があるときmixinを使うことがありますが、どちらかというと避ける方向性です。やむ得ないときと、ここぞというときのみに絞り使った方がよさそうです。

以下のツイートが参考になります。

:classや:styleの条件分岐

おまけです。classの条件分岐は、いろいろな方法がありまますが、三項演算子を使う場合が多くシンプルですね。

bool ? true : false;
<div :class="getData.name.includes('neru') === true ? 'bule' : 'green'">色変え</div>

あとは.bule{}と.green{}の2つのスタイルを用意すればOKです。

フッターページのトップだけ色を変えたい場合はこんなサンプルになります。

<div :class="this.$route.name === 'index' ? 'footer-top' : 'footer'">
</div>

さらに子コンポーネントだけClassを変えたい場合は三項演算子に加えて上記のpropsを使えばOKです。

:styleにも適応できます。

:style="!getData.types === true ? 'display:none;' : ''"

参考になれば幸いです。

コメント

タイトルとURLをコピーしました