Vue.js:将页面标题分配给不同的路线

Posted

技术标签:

【中文标题】Vue.js:将页面标题分配给不同的路线【英文标题】:Vue.js: Assigning page title to different routes [duplicate] 【发布时间】:2017-03-04 15:11:48 【问题描述】:

我正在使用 vue.js v1.0、vue-router v0.7 和 WebPack 构建一个 Web 应用程序。我遵循Single File Component 模式,每个页面都有不同的组件。

我不知道在浏览 Web 应用程序页面时如何更改不同路由(或者可能是不同组件)中的页面标题。我还希望页面标题在浏览器历史记录中可用。

【问题讨论】:

【参考方案1】:

除了我之前在此处发布的解决方案之外,我在经过一番研究后发现了第二种方法:使用Navigation Guards

正如我之前的回答中所详述的,问题出在:vue-router 第一次创建后可能会开始重用路由组件。确实没有必要在路由退出时销毁这些组件,并在后续路由进入时重新创建。因此,我之前的解决方案中的 created 挂钩可能不会在后续访问同一条路线时触发。因此,我们的窗口标题可能无法按预期工作。

为了解决这个问题,我们可以在 路由更改事件 上设置窗口标题。路由器实例有一个afterEach 钩子,它在路由更改后被调用。这可用于设置窗口标题,详情如下:

// Let's say this is your router instance, with all "Named Routes"
const ROUTER_INSTANCE = new VueRouter(
    mode: "history",
    routes: [
         path: "/", name: "HomeComponentName", component: HomeComponent ,
         path: "/about", name: "AboutComponentName", component: AboutComponent ,
         path: "*", name: "RouteErrorName", component: RouteError 
    ]
)

// Assign page titles for each of the "named routes"
// Reason: This allows us to have short named routes, with descriptive title
const PAGE_TITLE = 
    "HomeComponentName": "Your Dashboard",
    "AboutComponentName": "About Us Page",
    "RouteErrorName": "Error: Page not found"


ROUTER_INSTANCE.afterEach((toRoute, fromRoute) => 
    window.document.title = PAGE_TITLE[toRoute.name]
    console.log(toRoute)  // this lets you check what else is available to you here
)

如果您在类似的路线之间导航,例如“/user/foo”到“/user/bar”,这可能仍然对您没有帮助。如果您想要标题栏中的用户名或某些动态页面特定信息,请查看 Reacting to Params Changes,详细信息请参见 http://router.vuejs.org/en/essentials/dynamic-matching.html。根据文档,我们应该可以在组件中使用watch,如下所示:

watch: 
    '$route' (toRoute, fromRoute) 
        window.document.title = "some page title"
    

希望对你有帮助!

【讨论】:

这是一个完美、简单的解决方案。我将对象和afterEach 放在根Vue 组件的mounted() 函数中。随着页面列表的增长,将其提取到其他地方可能是值得的。 (TBH:我完全忘记了你可以通过 JS 设置窗口标题!)【参考方案2】:

前几天我也遇到了同样的问题,在我的路由组件定义中解决如下:

export default 
    created: function() 
        window.document.title = "Page Title for this route"
        ...
    ,
    ...

这确实不是正确的做法。原因:我做了一个很大的假设,即每次更改为新路由时都会创建 路由组件vue-router 目前是这样,但将来可能会改变。

我之前在 Angular 1.4 中使用ui-router,它允许 路由组件 存在于内存中(粘性状态),以便下次路由更改是即时的。如果 vue-router 曾经实现类似于 sticky states 的东西,我上面在 created 挂钩中设置标题的方法将失败。

但在此之前,您可以使用此解决方案。

【讨论】:

你的意思是“root组件”而不是“路由组件”吗? 我只指路由组件,即在<router-view></router-view> 内部呈现的组件。如果我们在其挂载的钩子中更改窗口标题,它将第一次工作。但是后来当旧的组件实例被重用时,挂载的钩子可能不会运行,因此窗口标题不会更新。【参考方案3】:

我有一个解决方案,并在我的projects 上使用了它。

首先创建一个指令。

Vue.directive('title', 
  inserted: (el, binding) => document.title = binding.value,
  update: (el, binding) => document.title = binding.value
)

假设,我们正在处理'MyComponent.vue' 文件。

然后在router-view 组件上使用该指令。

<router-view v-title="title" ></router-view>

export default 
  data()
    return 
      title: 'This will be the title'
    
  

即使组件已更新或页面已重新加载,此功能也有效。

对我来说效果很好!!

【讨论】:

似乎标题仅在定义 router-view 的地方定义。对于其他路线,这不会改变。

以上是关于Vue.js:将页面标题分配给不同的路线的主要内容,如果未能解决你的问题,请参考以下文章

Vue.js 组件 + Laravel 权限管理

Vue Websockets 双

带有路由器的 Vue.js 和 OMDb 页面

仍然无法将变量从烧瓶分配给 vue.js

将html页面连接到vue页面

如何将 Vue.js 2 组件值分配给主实例变量?