[英]How to use Vuetify tabs with vue-router
我有以下jsfiddle ,它有兩個 Vuetify 選項卡。 該文檔沒有顯示使用vue-router
示例。
我在Medium.com上找到了關於如何將 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 文檔沒有在他們的 api 中指定router
道具,因此帖子中的嵌入式示例不起作用。
我還發現了這個StackOverflow 答案,其中包含以下代碼:
<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 文檔中挖掘,為v-tabs-item
指定了to
道具。 似乎支持可能已在 1.0.13 中刪除。
如何將vue-router
與 Vuetify 選項卡一起使用?
聖哇! 我要求 Vuetify 社區向他們的 api 添加文檔,看起來他們只是將to
prop 以及其他vue-router
props 添加到Vuetify tabs docs 。 說真的,那里的社區很棒。
Vuetify 社區 Discord 中的人能夠幫助我。 我更新的jsfiddle現在有工作代碼。
本質上, v-tab
是router-link
的包裝器,我假設它使用插槽將道具傳遞給router-link
,因此將to
prop 放在v-tab
效果很好。
以下代碼是工作代碼的示例:
<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>
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,
});
模板部分:
<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
}
]
}
我只是在這里添加了一些與動畫相關的技巧,並闡明了v-tab-items
與v-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-tab
和v-tab-item
標簽上使用v-for
循環,只要在v-tab-item
的id
屬性中找到to
值即可。如果您需要將標簽內容放置在與標簽按鈕不同的位置,這就是
v-tab-items
的用途。 您可以將v-tab-item
放在v-tabs
組件外部的v-tab-items
標簽中。 確保給它一個v-model="activeTab"
屬性。
@roli-roli 和@antoni 的答案是正確的,但缺乏細節。 事實上,使用他們的方法(幾乎等價)在移動視圖中存在問題; 事實上,在這種情況下,標簽變得可滑動。 問題是滑動不會按預期更新路由,從帶有組件 A 的 Tab A 傳遞到帶有組件 B 的 Tab B; 相反,將觸發動畫並且activeTab
將更改,但路由器不會更新。
TL;DR 滑動v-tab-item
不會更新路由器,您會在每個選項卡下獲得相同的組件。
解決方案可以是禁用v-tab-item
的可滑動性或監聽tab
組件的更改事件以相應地更新路由器。 我會建議第二個解決方案(因為在某些情況下刷卡結果非常方便)
,但我認為這會在單擊選項卡標簽時觸發兩次路由器更新。
<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)
}
}
}
按照之前的答案進行設置。
//urls in some componet
<v-btn @click="goToUrl({name: 'RouteName1'})">
.....
<v-list-item-title
@click="goToUrl({name: 'RouteName2'})"
>
Some tab link text
</v-list-item-title>
....
//tabs menu and content in other component
<v-tabs>
<v-tab key="key_name1" :to="{ name: 'RouteName1'}">Some link 1</v-tab>
<v-tab key="key_name2" :to="{ name: 'RouteName2'}">Some link 2</v-tab>
<v-tab-item key="key_name1" value="/url/for/route1">
....
<v-tab-item key="key_name2" value="/url/for/route2">
....
我只想在切換到選項卡時為新組件的雙重安裝添加修復程序。 您可以在此處查看問題和答案。
TLDR 是,如果您在 中使用 v-for,您將遇到一個問題,即您要切換到的組件將被創建、銷毀,然后在每次切換時再次創建。 如果像我一樣,您在創建端執行 ajax 調用,那么您將在每次選項卡切換時點擊后端兩次。 你可以用 a 包裹來防止這種情況。
在回答中,我深入探討了為什么會發生這種情況。
以下代碼對我有用
<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>
並保留您現有的查詢參數:有用,例如,如果您的網址中有 :locale:
<v-tabs v-model="activeTab">
<v-tab v-for="tab in tabs" :key="tab.id" :to="tab.to">
{{ tab.name }}
</v-tab>
</v-tabs>
<v-tabs-items v-model="activeTab" @change="updateRouter($event)">
<v-tab-item v-for="tab in tabs" :key="tab.id" :value="tab.to">
<router-view />
</v-tab-item>
</v-tabs-items>
export default {
data: () => ({
activeTab: '',
}),
computed: {
tabs() {
return [
{ id: 1, name: 'Tab one', to: this.getTabPath('routeName1') },
{ id: 2, name: 'Tab two', to: this.getTabPath('routeName2') },
{ id: 3, name: 'Tab three', to: this.getTabPath('routeName3') },
{ id: 4, name: 'Tab four', to: this.getTabPath('routeName4') },
]
},
},
methods: {
getTabPath(name) {
// Get the path without losing params. Usefull e.g. if you have a :locale in your url:
return this.$router.resolve({ name, params: this.$route.params }).href
},
updateRouter(path) {
// Gets called upon swipe.
this.$router.push(path)
},
},
}
使用$router.resolve
作為解釋得到的路由對象的路徑在這里。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.