vue切换页面 动态设置meta和title标签内容

pc端项目中为了优化SEO搜索,要求首页和内容页的title/keywords/description 保持不一样
用vue+webpack搭建的项目

思路:

1)由于vue是单页面应用,index.html入口文件< head >标签只有一个,那么只能通过判断切换的路由

2)判断切换路由 需要在main.js全局js中 使用 router.beforeEach,to中可以获得将要去的组件的路由参数

3)如果title和meta标签内容是已经定好的,那就在router.js文件中设置需要辨别的参数–》在meta对象里自定义一个变量名 如:content / title,路由切换时直接读取

4)如果title和meta标签内容是后台配置的,我现在是请求接口获取。 传参是数字
可以在router.js文件中设置需要辨别的参数–》在meta对象里自定义一个数字变量名 如:index,这里有一个好处是哪些页面的title和meta标签内容是一样的 就可以设置一样的index,同样 路由切换时直接读取

5)下面就是请求接口,写个函数,该传参的传参,获取到接口的结果后 append给head标签

总体思路是这样,中间有些细节问题

1)刚进去的时候没有路由切换 或者切换完路由后刷新了页面 也就相当于没切换
有两种情况:一是第一次进入,index默认是首页的;二是切换了路由,这个可以在切换路由是记住这个变量
解决办法是:使用sessionstorage,无论首次还是刷新,只要改变储存的同一个变量

2)来回切换时 每次都创建一个新标签< meta > 和 < title >,需要销毁上一次的内容

3)路由里的index相同时 可以不请求,判断 router.beforeEach中to 和 from中参数

代码如下:

router.js

在routes的meta中自定义变量index

routes: [
    {
      path: '/',
      name: 'Index',
      component: Index,
      meta: {
       index: 1,        // 自定义标识
        keepAlive: true
      }
    },
    {
      path: '/consult/newslist',
      name: 'Newslist',
      component: Newslist,
      meta: {
        index: 2,       // 自定义标识
        keepAlive: true
      }

},
{
  path: '/consult/details',
  name: 'Details',
  component: Details,
  meta: {
    index: 2,      // 同样的标识
    keepAlive: true
  }
}]

main.js

该文件是全局的,最好写在代码块里
概要:创建meta标签,定义name属性,写好方法
1)利用本地存储,获取组件index,调用方法
2)切换router时,获取组件index,调用方法

{

  let head = document.getElementsByTagName('head');        // 创建head标签
  let meta1 = document.createElement('meta');           // 创建meta标签
  let meta2 = document.createElement('meta');
  
  meta1.name = "keywords";                         // 设置name
  meta2.name = "description";
	
  function getMetaContent(index, h, m1, m2){
    $.ajax({
      type: 'POST',
      url: urlhost+'/news/page',
      data$Type: 'jsonp',
      data: {
        type: index
      },
      success: (res) => {
        let data = JSON.parse(res)
        if(data.status == 0) return;
        let list = data.message[0];
        let key = list.keywords;
        let desc = list.description;
        let title = list.title;
        document.title = title || '设置默认内容';
        m1.content = key || '设置默认内容';
        m2.content = desc || '设置默认内容';
        h[0].appendChild(m1)
        h[0].appendChild(m2)
      }
    })
  }
  
  let cIndex = sessionStorage.currentRouteIndex;                 // 先保存一把
  if(cIndex){
    cIndex = parseInt(cIndex);
    getMetaContent(cIndex, head, meta1, meta2)
  }else{
    getMetaContent(1, head, meta1, meta2)
    sessionStorage.currentRouteIndex = 1                 // 首次 进入
  }
  
  router.beforeEach((to, from, next) =>{
    let i = to.meta.index;
    let j = from.meta.index;
    if(i == j) return                            // 减少请求次数
    
    if(meta1.name == "keywords" || meta2.name == "description"){     // 如果之前有获取过关键字,先清空内容
      meta1.content = '';
      meta2.content = '';
    }
    sessionStorage.setItem('currentRouteIndex', i)       // 保存到浏览器中去
    getMetaContent(i, head, meta1, meta2);
    next()
  })
}

你可能感兴趣的:(share,discuss,vue)