I can fly!!

地元ITベンダー→公務員→フルリモートのフリーランス Webエンジニア もうすぐ2児の父

[Vuetify] v-tab-itemの子要素は、タブがactive化した時に初めてレンダリングされる

少しハマったのでメモ。

v-tab-itemはタブがactive化した時に初めて子要素のレンダリングを行うのがデフォルトの動き。コンポーネントのマウント時にレンダリングしてほしい場合は、eagerオプションを使う。

Vuetifyドキュメント

vuetifyjs.com

eagerオプションを付けない場合

デモはこちら

// vueファイル
<div id="app">
  <v-app id="inspire">
    <v-card color="basil">
      <v-card-title class="text-center justify-center py-6">
        <h1 class="font-weight-bold display-3 basil--text">BASiL</h1>
      </v-card-title>
  
      <v-tabs
        v-model="tab"
        background-color="transparent"
        color="basil"
        grow
      >
        <v-tab
          v-for="item in items"
          :key="item"
        >
          {{ item }}
        </v-tab>
      </v-tabs>
  
      <v-tabs-items v-model="tab">
        <v-tab-item
          v-for="item in items"
          :key="item"
        >
          <v-card flat color="basil" :id="item">
            <v-card-text>{{ text }}</v-card-text>
          </v-card>
        </v-tab-item>
      </v-tabs-items>
    </v-card>
  </v-app>
</div>
// jsファイル
new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data () {
    return {
      tab: null,
      items: [
        'Appetizers', 'Entrees', 'Deserts', 'Cocktails',
      ],
      text: 'testtesttest.',
    }
  },
  mounted() {
    console.log(document.getElementById("Appetizers"));
    console.log(document.getElementById("Entrees"));
    console.log(document.getElementById("Deserts"));
    console.log(document.getElementById("Cocktails"));
  }
})

jsファイルのmountedフックでv-tab-itemの子要素をid指定で取得しようとするが、結果はnullが返ってくる。active化前なのでまだレンダリングされていない。

f:id:hide0721yana:20200120220343p:plain
要素を取得できない

chromeのデバッガを見てみても、active化されていない要素の子要素はレンダリングされていない。

f:id:hide0721yana:20200120220825p:plain
子要素がレンダリングされていない

eagerオプションをつけた場合

デモはこちら

// vueファイル
<div id="app">
  <v-app id="inspire">
    <v-card color="basil">
      <v-card-title class="text-center justify-center py-6">
        <h1 class="font-weight-bold display-3 basil--text">BASiL</h1>
      </v-card-title>
  
      <v-tabs
        v-model="tab"
        background-color="transparent"
        color="basil"
        grow
      >
        <v-tab
          v-for="item in items"
          :key="item"
        >
          {{ item }}
        </v-tab>
      </v-tabs>
  
      <v-tabs-items v-model="tab">
        <v-tab-item
          v-for="item in items"
          :key="item"
          eager     <!--  <=  コレ!!!  -->
        >
          <v-card flat color="basil" :id="item">
            <v-card-text>{{ text }}</v-card-text>
          </v-card>
        </v-tab-item>
      </v-tabs-items>
    </v-card>
  </v-app>
</div>

eagerオプションを使うと、コンポーネントマウント時に子要素までレンダリングされるので、mountedフック内でv-tab-itemの子要素を取得できる。

f:id:hide0721yana:20200120221504p:plain
v-tab-itemの子要素を取得できた

デバッガで確認しても、ちゃんとレンダリングされているのがわかる。

f:id:hide0721yana:20200120221511p:plain
v-tab-itemの子要素がレンダリングされている

以上。