Vue Router 动态设置Meta

问题描述 投票:0回答:5

所以我有一个使用 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
}

这确实改变了它,但不是在导航栏已经加载之前。

javascript vue.js vue-router
5个回答
14
投票

我在元数据中的动态 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>

8
投票

设置元后,我强制路由器重新加载,如下所示:

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 中找到了许多强制重新加载路由器的解决方法。这只是其中之一。


7
投票

您可以使用

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


2
投票

meta
对象设置为函数可防止将其值合并到所有匹配的路由。来自文档

...Vue Router 还为您提供了

$route.meta
,它是从父级到子级的所有元字段的非递归合并。

最好的解决方案是将特定元属性的值设置为函数。例如,使用 Pinia:

meta: {
  title: () => useProjectsStore()?.currentItem?.title || 'Project dashboard',
}

然后,在使用它的值之前,检查它的类型:

  {{
    typeof item.meta?.title === 'function' 
    ? item.meta.title()
    : item.meta?.title
  }}

0
投票
// 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
© www.soinside.com 2019 - 2024. All rights reserved.