vue hash模式改成history,同时实现spa预渲染

1.前言


由于公司需要把首页进行seo排名,但是首页已经完成好,并且还是hash模式,要做成seo排名,不能有hash模式的#,同时要能读取到渲染好的页面.所以,针对这2点困难,最终想到的解决方案是:

  1. 先hash需要转换为history,保证是无#的美观模式;
  2. 需要做到提前渲染好,可以采取vue的SSR,spa预渲染或nuxt.js.

2.选取渲染方式


首先,hash转换为history已经是板上钉钉的事情,这时候就开始找快捷简单改动少的渲染方式,分别有vue的SSR,spa和nuxt.js.

  1. vue项目提供了ssr的方案.不过ssr方案需要在node上调用 renderToString 来渲染。如果不介意在系统结构中增加一层 node 的话,就可以使用ssr的方式,这种方式会改变前后端交互的方式。ssr文档.改动中等
  2. spa预渲染,即使用prerender-spa-plugin插件预渲染.由于页面较少,且预渲染相对于SSH比较简单,于是选择预渲染页面,预渲染可以极大的提高网页访问速度。而且配合一些meat插件,基本可以满足SEO需求。改动在三者中最小
  3. Nuxt就是基于Vue的一个应用框架,采用服务端渲染,让你的SPA应用(Vue)也可以拥有SEO.官方文档,但是由于需要重新改变底层框架,改动在三者中最大.

综上所述,选择第二个方式,spa预渲染,改动小,同时也能达到seo的要求

3.hash转为history


1.模式修改 (目录:src/router/index.js)

 // mode:'hash',
    mode: 'history',
    base: '/',

2.相对路径调整

2.1 目录:build/webpack.prod.conf.js

//history为"/",hash:'./'
//publicPath:'./',
publicPath:'/',

2.2目录:config/index.js

// histroy模式:"/" ,hash模式:"./"
//assetsPublicPath: './',
assetsPublicPath: '/',

2.3 修改原因:

./ 是指用户所在的当前目录(相对路径);

/ 是指根目录(绝对路径,项目根目录),也就是项目根目录;

对于hash模式,根路径是固定的,就是项目的根目录,但是history模式下,以/开头的嵌套路径会被当作根路径,所以使用“./”引入文件,就会找不到文件了,因为文件本身就是在项目根目录下的,并不在嵌套路径这个目录下。

总结,无论hash模式还是history模式,可以直接使用“/”从项目根目录引入静态文件。

3.服务端修改

nginx配置: 参考官网教程

location / {
    proxy_pass http://127.0.0.1:80;
    root /usr/local/tomcat/tomcat_xhcf/webapps/ROOT; #表明路径
    index index.html index.htm; 
    try_files $uri $uri/ /index.html; #交给index.html处理
    
}

原因:这样修改,避免了刷新404的问题,因为如果URL匹配不到任何静态资源,就跳转到默认的index.html进行处理.

4.SPA预渲染


1.安装prerender-spa-plugin

npm i -s prerender-spa-plugin

或者 (淘宝镜像)

cnpm i --save prerender-spa-plugin

2.配置

2.1目录:build/webpack.prod.conf.js

在plugins列表里,加入下面代码:

// 在vue-cli生成的文件的基础上,只有下面这个才是我们要配置的
    new PrerenderSPAPlugin({
      // 生成文件的路径,也可以与webpakc打包的一致。
      // 下面这句话非常重要!!!
      // 这个目录只能有一级,如果目录层次大于一级,在生成的时候不会有任何错误提示,在预渲染的时候只会卡着不动。
      staticDir: path.join(__dirname, '../dist'),

      // 对应自己的路由文件,比如index有参数,就需要写成 /index/param1。这里很重要,需要把自己想要生成静态文件的路由全部写进去。
      routes: [
        '/',
        '/about',
        ],

      // 这个很重要,如果没有配置这段,也不会进行预编译
      renderer: new Renderer({
        inject: {
          foo: 'bar'
        },
        headless: false,
        // 在 main.js 中 document.dispatchEvent(new Event('render-event')),两者的事件名称要对应上。
        renderAfterDocumentEvent: 'render-event',
        //时间
        renderAfterTime:5000
      })
    })

2.2目录:src/main.js (mounted是新增代码,对应build/webpack.prod.conf.js里加的)

/* 记得要通过 router 配置参数注入路由,从而让整个应用都有路由功能*/
const app =new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>',

  /* 这句非常重要,否则预渲染将不会启动 */
  mounted () {
    document.dispatchEvent(new Event('render-event'))
  }

}).$mount('#app')

最终npm run build ,生成代码,目录如下即成功


dist
│    ├── about          
│           └── index.html           
│   
├── index.html      
└── static

5.全程操作概览


1.修改完以上全部配置;

2.项目里npm run build生成文件,放入对应服务器目录;

3.nginx重启配置:

nginx -t #测试配置是否正确
nginx -s reload #重启nginx配置

大功告成!

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页