如何在使用vue-router时更改页面标题?

dar*_*rse 13 vue.js vue-router vuejs2

如果可能的话,我想在路线定义中指定我的标题.通常在<head><title>浏览器标题栏中指定和显示的内容.

我的项目设置如下:

main.js

import Vue from 'vue'
import App from './App.vue'
import VeeValidate from 'vee-validate';
import router from './router'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';

Vue.use(VeeValidate);
Vue.use(ElementUI);
Vue.config.productionTip = false

new Vue({
    router,
    render: h => h(App)
}).$mount('#app')
Run Code Online (Sandbox Code Playgroud)

router.js

import Vue from 'vue'
import Router from 'vue-router'
import Skills from './components/Skills.vue'
import About from './components/About.vue'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'skills',
      component: Skills,
      meta: { title: 'Skills - MyApp' } // <- I would to use this one
    },
    {
      path: '/about/:name',  // Add /:name here
      name: 'about',
      component: About,
      meta: { title: 'About - MyApp' }
    }
  ]
})
Run Code Online (Sandbox Code Playgroud)

最好是,我想要一个自动系统,而不是在每个组件的创建功能上更改页面标题.谢谢.

Ste*_* B. 22

您可以使用带有路由器定义的导航防护:

const DEFAULT_TITLE = 'Some Default Title';
router.afterEach((to, from) => {
    document.title = to.meta.title || DEFAULT_TITLE;
});
Run Code Online (Sandbox Code Playgroud)

您需要将导出更改为:

const router = new Router({ ... });
...
export default router;
Run Code Online (Sandbox Code Playgroud)

或者您可以在根组件上使用观察程序:

export default {
    name: 'App',
    watch: {
        $route(to, from) {
            document.title = to.meta.title || 'Some Default Title';
        },
    }
};
Run Code Online (Sandbox Code Playgroud)

  • 我想我认为在这种情况下,“ afterEach”是更好的做法,因为在导航可以发生之前这并不是必须要做的事情(例如,身份验证检查在“ beforeEach”中进行,因为它们有可能取消导航,在导航已经确认的情况下更新“ afterEach”中的视觉内容),但我认为这对性能没有任何影响,如果您唯一要做的就是这样做。 (4认同)
  • @CatoMinor 我更新了我的答案。从测试来看,观察者方法在没有“nextTick”的情况下似乎可以正常工作。 (2认同)

W K*_*nny 18

2021 年最新作品方式 - Vue3:

添加相关组件的行名称.\router\index.js

  {
  path: '/',
  name: 'Home page'
  },
Run Code Online (Sandbox Code Playgroud)

将其加载到BeforeEach这个函数中也将其写入.\router\index.js

router.beforeEach((to, from, next) => {
  document.title = to.name;
  next();
});
Run Code Online (Sandbox Code Playgroud)

  • 应该可以工作,但该名称也用于“命名路由”,用作代码;不太可能像“主页”那样被人类阅读 (3认同)

non*_*oat 9

高级变体

使用 vue-meta

第一次运行 npm install vue-meta

并将其包含到您的main.js 中

import VueMeta from 'vue-meta'
Vue.use(VueMeta)
Run Code Online (Sandbox Code Playgroud)

这样做之后,您可以metaInfo()每个 vue 组件添加一个方法,处理元数据;

metaInfo() {
        return { 
            title: "Epiloge - Build your network in your field of interest",
            meta: [
                { name: 'description', content:  'Epiloge is about connecting in your field of interest. Our vision is to help people share their knowledge, work, projects, papers and ideas and build their network through what they do rather where they live, study or work.'},
                { property: 'og:title', content: "Epiloge - Build your network in your field of interest"},
                { property: 'og:site_name', content: 'Epiloge'},
                {property: 'og:type', content: 'website'},    
                {name: 'robots', content: 'index,follow'} 
            ]
        }
    }
Run Code Online (Sandbox Code Playgroud)

此外,这可用于动态元信息

export default{
    name: 'SingleUser',
    data(){
        return{
            userData: {},
            ...
            aws_url: process.env.AWS_URL,
        }
    },  
    metaInfo() {
        return {
            title: `${this.userData.name} - Epiloge`,
            meta: [
                { name: 'description', content: 'Connect and follow ' + this.userData.name + ' on Epiloge - ' + this.userData.tagline},
                { property: 'og:title', content: this.userData.name + ' - Epiloge'},
                { property: 'og:site_name', content: 'Epiloge'},
                { property: 'og:description', content: 'Connect and follow ' + this.userData.name + ' on Epiloge - ' + this.userData.tagline},
                {property: 'og:type', content: 'profile'},
                {property: 'og:url', content: 'https://epiloge.com/@' + this.userData.username},
                {property: 'og:image', content: this.aws_url + '/users/' + this.userData.profileurl + '-main.jpg' }    
            ]
        }
    },
    ...
}
Run Code Online (Sandbox Code Playgroud)

资料来源:Medium - 如何为 Google SEO 向 Vue.js 应用程序添加动态元标签


car*_*ist 8

我想补充一点,上面并没有真正保留历史。请参阅https://github.com/vuejs/vue-router/issues/914#issuecomment-384477609以获得更好的答案,它实际上照顾了历史(尽管有点老套)。


Vas*_*nin 7

有了 Vue 3,我就得到了这个解决方案:

const routes = [  
  {
    path: '/calendar',
    name: 'calendar',
    meta: { title: 'My Calendar' },
    component: CalendarForm
  },
  {
    path: '/',
    name: 'main',
    meta: { title: 'Home page' },
    component: MainForm
  }  
]

const router = createRouter({
  history: createWebHashHistory(),
  routes
})

router.beforeEach((to, from, next) => {
  console.log(to);
  document.title = to.meta.title;
  next();
});

export default router
Run Code Online (Sandbox Code Playgroud)


Yak*_*ovL 5

实际上,根据我对 Steven B. 解决方案的实验,我想出了更好的方法。事情是这样的

watch: {
    $route(to, from) {
        document.title = to.meta.title || 'Some Default Title';
    },
}
Run Code Online (Sandbox Code Playgroud)

当我们最初访问页面时不起作用(通过浏览器的地址栏导航)。相反,我们可以像这样创建一个 getter:

computed: {
    pageTitle: function() {
        return this.$route.meta.title;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,在我的情况下,我希望设置“模板”的标题(以便子路由不会打扰它),就是这样;对于您的情况,您可能想知道如何在计算属性后设置文档的标题,并且有一些方法。根据这些答案,您甚至可以执行以下操作:

created () {
    document.title = this.$route.meta.title;
}
Run Code Online (Sandbox Code Playgroud)

但是我会针对在生产中使用之前重新访问同一页面(不确定是否每次都创建组件)的情况进行测试。