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

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

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

【问题讨论】:

    标签: javascript vue.js vue-router


    【解决方案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 的地方定义。对于其他路线,这不会改变。
    猜你喜欢
    • 2018-10-31
    • 2014-02-06
    • 1970-01-01
    • 2017-07-10
    • 2022-01-24
    • 2020-10-05
    • 2019-01-25
    • 1970-01-01
    • 2020-01-09
    相关资源
    最近更新 更多