所以我有一个使用 Vue 和 Vue Router 的 SPA。它的设置类似于 iOS 应用程序,当您深入单击视图时,导航栏中的标题会发生变化。现在我已经将其硬编码在routes.js 文件中,但希望使其成为动态的。我可以在视图中更新路线元,但该元数据在视图显示后呈现,因此我需要在路线更改之前进行更新。这是设置:
route.js
//A route
{
path: '/team/:username',
component: require('./views/team-single'),
name: 'profile',
meta:{ requiresAuth: true, title: 'Team Member', tabbar: false }
}
导航栏.vue
//if the route has a title show that not the logo
<div class="navbar-item">
<transition name="fadeup">
<h1 v-if="$route.meta.title" class="navbar-title">{{ $route.meta.title }}</h1>
<img src="/img/hopbak-green.svg" class="navbar-logo" alt="hopbak" v-else>
</transition>
</div>
所以理想情况下,将 :username 传递到 Route.js 中的标题中会很好,但我认为这是不可能的。我尝试过将类似的内容添加到视图中,但就像我说的那样,它被调用得很晚:
团队成员.vue
mounted(){
this.$route.meta.title = this.user.username
}
这确实改变了它,但不是在导航栏已经加载之前。
我在元数据中的动态 url 参数上遇到了类似的问题,我通过将
this.$route
的元属性评估为函数来解决它。首先这样配置meta属性:
//A route
{
path: '/team/:username',
component: require('./views/team-single'),
name: 'profile',
meta: (route) => ({ requiresAuth: true, title: 'Team Member' + route.params.username, tabbar: false })
}
然后你可以这样在你的模板中使用它:
//if the route has a title show that not the logo
<div class="navbar-item">
<transition name="fadeup">
<h1 v-if="$route.meta != null" class="navbar-title">{{ $route.meta($route).title }}</h1>
<img src="/img/hopbak-green.svg" class="navbar-logo" alt="hopbak" v-else>
</transition>
</div>
设置元后,我强制路由器重新加载,如下所示:
this.$route.meta.title = this.user.username
// Add a temporary query parameter.
this.$router.replace({query: {temp: Date.now()}})
// Remove the temporary query parameter.
this.$router.replace({query: {temp: undefined}})
在此 GitHub issue 中找到了许多强制重新加载路由器的解决方法。这只是其中之一。
您可以使用
props
来实现这样的目标。
{
path: '/team/:username',
name: 'profile',
component: require('./views/team-single'),
props: (route) => ({ title: route.params.username })
}
并且,在组件中:
props: ['title'],
...
mounted () {
console.log('title: ' + this.title)
}
...
查看文档了解更多信息:https://router.vuejs.org/en/essentials/passing-props.html
将
meta
对象设置为函数可防止将其值合并到所有匹配的路由。来自文档:
...Vue Router 还为您提供了
,它是从父级到子级的所有元字段的非递归合并。$route.meta
最好的解决方案是将特定元属性的值设置为函数。例如,使用 Pinia:
meta: {
title: () => useProjectsStore()?.currentItem?.title || 'Project dashboard',
}
然后,在使用它的值之前,检查它的类型:
{{
typeof item.meta?.title === 'function'
? item.meta.title()
: item.meta?.title
}}
// literal string path
router.push('/users/eduardo')
// object with path
router.push({ path: '/users/eduardo' })
// named route with params to let the router build the url
router.push({ name: 'user', params: { username: 'eduardo' } })
// with query, resulting in /register?plan=private
router.push({ path: '/register', query: { plan: 'private' } })
// with hash, resulting in /about#team
router.push({ path: '/about', hash: '#team' })
const userId = '123'
router.push({ name: 'user', params: { userId } }) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
// This will NOT work
router.push({ path: '/user', params: { userId } }) // -> /user