web-dev-qa-db-ja.com

Vue-RouterでVuetifyタブを使用する方法

次の jsfiddle があり、2つのVuetifyタブがあります。ドキュメントには、vue-routerの使用例は示されていません。

私はこれを見つけました Medium.com post Vuetifyをvue-routerと共に使用する方法について、次のコードがあります:

<div id="app">
  <v-tabs grow light>
    <v-tabs-bar>
      <v-tabs-item href="/" router>
        <v-icon>motorcycle</v-icon>
      </v-tabs-item>
      <v-tabs-item href="/dog" router>
        <v-icon>pets</v-icon>
      </v-tabs-item>
    </v-tabs-bar>
  </v-tabs>

  <router-view />
</div>

ただし、 Vuetify 1.0.13 Tabs documentation がapiでrouter propを指定していないため、コードは古いため、投稿に埋め込まれた例は機能しません。

また、これを見つけました StackOverflow answer 次のコードがありました:

<v-tabs-item :to="{path:'/path/to/somewhere'}">

ただし、toプロップの使用は機能せず、Vuetify APIにもリストされていません。対照的に、v-button Vuetifyコンポーネントはto propをリストし、vue-routerを使用するため、vue-routerサポートされているコンポーネントがto propをサポートすることを期待します。

古い 古いVuetify 0.17 docs を掘り下げて、v-tabs-itemtoプロップが指定されています。 1.0.13ではサポートが削除されたようです。

vue-routerをVuetifyタブで使用するにはどうすればよいですか?

35
homersimpson

更新

すごい! VuetifyコミュニティにAPIにドキュメントを追加するように依頼しましたが、toプロップと他のvue-routerプロップを Vuetify tabs docs に追加したようです。真剣に、そこのコミュニティは素晴らしいです。

元の回答

VuetifyコミュニティDisc​​ordの人々は私を助けてくれました。更新された jsfiddle に作業コードが追加されました。

基本的に、v-tabrouter-linkのラッパーであり、スロットを使用して小道具をrouter-linkに渡すと想定しているため、v-tabto小道具を置くとうまく機能します。

次のコードは、作業コードの例です。

html

<v-app dark>
  <v-tabs fixed-tabs>
    <v-tab to="/foo">Foo</v-tab>
    <v-tab to="/bar">Bar</v-tab>
  </v-tabs>
  <router-view></router-view>
</v-app>

js

const Foo = {
  template: '<div>Foo component!</div>'
};

const Bar = {
  template: '<div>Bar component!</div>'
};

const routes = [
  { path: '/foo', component: Foo },
  { path: '/bar', component: Bar },
];

const router = new VueRouter({ routes });

new Vue({
  el: '#app',
  router,
});

結果

Foo tab exampleBar tab example

37
homersimpson

ここにアニメーション関連のヒントをいくつか追加し、v-tab-itemsv-tab-itemの使用を明確にします。

気付いた場合、次のように作業マークアップを使用すると、v-tabsタブスイッチアニメーションが機能しなくなります。

<v-tabs v-model="activeTab">
  <v-tab key="tab-1" to="/tab-url-1">tab 1</v-tab>
  <v-tab key="tab-2" to="/tab-url-2">tab 2</v-tab>
</v-tabs>
<router-view />

タブスイッチのアニメーションを保持したい場合、これがその方法です。

<v-tabs v-model="activeTab">
  <v-tab key="tab-1" to="/tab-url-1" ripple>
    tab 1
  </v-tab>
  <v-tab key="tab-2" to="/tab-url-2" ripple>
    tab 2
  </v-tab>

  <v-tab-item id="/tab-url-1">
    <router-view v-if="activeTab === '/tab-url-1'" />
  </v-tab-item>
  <v-tab-item id="/tab-url-2">
    <router-view v-if="activeTab === '/tab-url-2'" />
  </v-tab-item>
</v-tabs>

v-forsのto属性の中にid値が見つかっている限り、v-tabおよびv-tab-itemタグでv-tab-itemループを使用することもできます。

タブのコンテンツをタブボタンとは異なる場所に配置する必要がある場合、これがv-tab-itemsの目的です。 v-tab-itemsは、v-tab-itemsコンポーネントの外部のv-tabsタグに配置できます。必ずv-model="activeTab"属性を指定してください。

10
antoni

テンプレート部分:

<div>
    <v-tabs
      class="tabs"
      centered
      grow
      height="60px"
      v-model="activeTab"
    >
      <v-tab v-for="tab in tabs" :key="tab.id" :to="tab.route" exact>
        {{ tab.name }}
      </v-tab>
    </v-tabs>
    <router-view></router-view>
</div>

そして、jsの部分:

  data() {
    return {
      activeTab: `/user/${this.id}`,
      tabs: [
        { id: 1, name: "Task", route: `/user/${this.id}` },
        { id: 2, name: "Project", route: `/user/${this.id}/project` }
      ]
    };
  }

ルート:

{
  path: "/user/:id",
  component: User1,
  props: true,
  children: [
    {
      path: "", //selected tab by default
      component: TaskTab
    },
    {
      path: "project",
      component: ProjectTab
    }
  ]
}

codesanboxの例を参照

9
roli roli

@ roli-roliと@antoniの答えは正しいですが、細かい詳細が欠けています。実際、それらのメソッド(ほぼ同等)を使用すると、モバイルビューに問題があります。実際、このような状況ではタブはスワイプ可能になります。問題は、スワイプしても期待どおりにルートが更新されず、コンポーネントAのタブAからコンポーネントBのタブBに渡されることです。代わりに、アニメーションが発生し、activeTabが変更されますが、ルーターは更新されません。

TL; DR [v-tab-item]をスワイプしてもルーターは更新されず、各タブに同じコンポーネントが表示されます。

解決策は、v-tab-itemのスワイプ機能を無効にするか、tabコンポーネントの変更イベントをリッスンして、それに応じてルーターを更新することです。私はこの2番目の解決策をアドバイスします(特定の条件でスワイプの結果がかなり便利なので)、しかし、タブのラベルをクリックするとルーターの更新が2回トリガーされると思います。

@ roli-roliの回答に基づく実用的な例を次に示します

テンプレート

<template>
    <v-tabs v-model="activeTab">
        <v-tab v-for="tab in tabs" :key="tab.id" :to="tab.route">{{ tab.name }}</v-tab>

        <v-tabs-items v-model="activeTab" @change="updateRouter($event)">
            <v-tab-item v-for="tab in tabs" :key="tab.id" :to="tab.route">
                <router-view />          
            </v-tab-item>
        </v-tabs-items>
    </v-tabs>
</template>

脚本

export default {
    data: () => ({
        activeTab: '',
        tabs: [
            {id: '1', name: 'Tab A', route: 'component-a'},
            {id: '2', name: 'Tab B', route: 'component-b'}
        ]
    }),
    methods: {
        updateRouter(val){
            this.$router.Push(val)
        }
    }
}

ルーター

前の回答のように設定します。

3
Gabriel Rambaud

次のコードは私のために働く

  <v-tabs fixed-tabs>
          <v-tab>Locations</v-tab>
          <v-tab>Employees</v-tab>
          <v-tab-item>Tab 1 content
            <locations-data/>
          </v-tab-item>
          <v-tab-item>Tab 2 content
            <employees-data/>
          </v-tab-item>
    </v-tabs>
   <script>
        import LocationsData from './Settings/Locations';
        import EmployeesData from './Settings/Employees';
        export default {
           components: {
            LocationsData,
            EmployeesData
          },
        }
   </script>