[英]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.