vue router中hash模式和history模式共存研究

2,392 阅读1分钟

The possibility of coexisting with hash mode and history mode in one program.
背景:一个H5工程,之前使用的是hash模式,现在想改成history模式,但之前的业务不能修改,所以想到了两个模式共存的问题。

在vue-router官方文档的devServer小节中,这样描述:

Some values like publicPath and historyApiFallback should not be modified as they need to be synchronized with publicPath for the dev server to function properly.

然后我发现了这个问题的解决办法。 在工程项目的vue配置文件vue.config.js中,你可以向devServer中添加如下的配置:

historyApiFallback: {
      verbose: true,
      rewrites: [
        { from: /^\/history\/.*$/, to: '/history.html' }
      ]
    }

# 值得注意的是,这里的rewrites是本地的配置。当项目发布到线上时,服务器端(像nginx)也需要做同样的配置。

然后在routes中,路径必须像下面这样配置:

let routes = [
  {
    path: '/history/qualityAlliance',
    name: 'qualityAlliance',
    component: () => import('views/qualityAlliance/index')
  }
]
# 在这种情况下,path不能写成'/qualityAlliance',也就是说history不能省略
# 或者把history字段统一添加到Router的base路径中

在pages中,你可以这样做:

pages: {
    main: {
      ....
      // hash模式
    },
    routerHistory: {
      // history模式
      entry: 'src/entry/history.js', // 另外一个entery
      template: 'public/history.html', // 另外一个template
      filename: 'history.html',
      title: ''
    }
  },

然后在浏览器上输入http://localhost:8080/history/qualityAlliance (history 模式),它能正常工作,并且没有自动往地址中添加#/后缀。 接着在浏览器上输入http://localhost:8080/#/history/qualityAlliance (hash模式), 当然能正常运行啦!

链接:Is there the possibility of coexisting with hash mode and history mode in one program

备注

nginx可参考如下配置:

    server {
        ....
        rewrite  ^/path/history/(.*)/(css|js|static|img|libs)/(.*)$  /path/history/$2/$3 last; #此为perl正则表达式写法
        location /path/history { #history模式
            alias /Users/xxx/Documents/nginx/path;
            index  history.html;
            try_files $uri $uri/ /history.html =404;
        }
        
        location /path { #hash模式
            alias /Users/xxx/Documents/nginx/path;
            index  index.html;
            try_files $uri $uri/ /index.html = 404;
        }
        ...
    }

本文思想:

由于history模式需要与hash模式共存,因此需要从路径上进行区分。以history作为特殊字段,进行识别转发。在位置/path/history的设置中,需要设置别名alias(非root)。由于路径中多了一层虚拟的文件夹,因此需要进行重写rewrite。把路由下不能识别的静态资源,如css,js等,转发到history下;而history又是真正路径的别名,因此可以转发到实际的资源位置上。