vue 的路由在默认的 hash 模式下,默认打包一般不会有什么问题,不过 hash 模式由于 url 会带有一个 # 不美观,而且在微信分享,授权登录等都会有一些坑,所以此时 history 模式就很好用了。
先看问题
但是往往会碰到 history 模式打包后页面一片空白的情况,而且没有资源加载错误的报错信息emmm!!!
这个其实仔细研究下会发现,如果项目直接放的根目录,那是没有问题的,如果是子目录,那么就会一片空白了:这个 vue 官方有解释,需要加一个 base,这个base即为项目路径
// mode: 'history', // base: '/dist/',
但是!!
此时只有首页能访问,通过首页点进去其他路由也是可以的,但是如果在其它页路由刷新就有错误了,这个懂 history 模式的也应该知道,history 模式是 h5 api 的 history.pushState,相对于是浏览器模拟了一条历史,而真正服务器上没有这个路径资源,为什么 hash 模式不存在这个问题呢?hash 模式是带#,这个服务器不会解析,相对于还是返回 html 而已,index.html 会根据 vue 路由去解析,而 history 模式则会请求服务器上的此地址,服务器上没有相关路径就会报错了,所以出问题也就不奇怪了。
解决方法(nginx配置)
vue-router 的官方文档有介绍各种配置,比如 ngnix 的配置。
location / { try_files $uri $uri/ /index.html; }
上面这个配置:对于直接放置在根目录的项目是可以的,但是如果项目不是在根目录还是会有问题!!!
location /dist { root C:/web/static; index index.html index.htm; #error_page 404 /dist/index.html; if (!-e $request_filename) { rewrite ^/(.*) /dist/index.html last; break; } }
上面这个是项目路径名为 history ,这样配置后就不会有 vue 打包后页面空白问题了,history 路由也可以自由访问了,不过要记得上面说的,非根目录的项目需要加上 base 的路径。
实际应用:完整代码
1、config 文件夹中 index.js 打包配置:更改这个属性:assetsPublicPath:'/dist/'
示例:
assetsPublicPathbuild: { // Template for index.html index: path.resolve(__dirname, '../dist/index.html'), // Paths assetsRoot: path.resolve(__dirname, '../dist'), assetsSubDirectory: 'static', assetsPublicPath: '/dist/', // 使用绝对路径 /** * Source Maps */ productionSourceMap: true, // https://webpack.js.org/configuration/devtool/#production devtool: '#source-map', // Gzip off by default as many popular static hosts such as // Surge or Netlify already gzip all static assets for you. // Before setting to `true`, make sure to: // npm install --save-dev compression-webpack-plugin productionGzip: false, productionGzipExtensions: ['js', 'css'], // Run the build command with an extra argument to // View the bundle analyzer report after build finishes: // `npm run build --report` // Set to `true` or `false` to always turn it on or off bundleAnalyzerReport: process.env.npm_config_report }
2、路由配置:router 文件夹下 index.js:增加
示例:
mode: 'history', // 去掉#,需要路由模式改为 history
base: '/dist/', // 这个配置也很重要,否则会出现页面空白情况
export default new Router({ mode: 'history', // 去掉#,需要路由模式改为history base: '/dist/', // 这个配置也很重要,否则会出现页面空白情况 scrollBehavior: () => ({ y: 0 }), routes: [ { path: '/facebook', name: 'Facebook', component: Facebook }, { path: '/google', name: 'Google', component: Google } ] })
3、build 文件夹中 webpack.prod.conf.js
更改这个属性:publicPath
output: { // publicPath: "./", // 原来 相对路径 publicPath:config.build.assetsPublicPath, // 改为绝对路劲 这个配置很重要,否则会出现子级页面空白情况 path: config.build.assetsRoot, filename: utils.assetsPath('js/[name].[chunkhash].js'), chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') },
4、nginx 配置不懂就要找你得运维或者后端小伙伴了
location / { root /opt/payment/soft/nginx/html/helloweb/dist; access_log /opt/payment/soft/nginx/logs/helloweb.log main; error_log /opt/payment/soft/nginx/logs/helloweb_error.log ; index index.html; try_files $uri $uri/ /index.html; if (!-e $request_filename) { rewrite ^/(.*) /index.html last; break; } if ($http_user_agent ~* "(Windows|Macintosh)") { return 301 https://www.helloweb.wang; } }
总结
原理:
./
是指用户所在的当前目录(相对路径);
/
是指根目录(绝对路径,项目根目录),也就是项目根目录;
对于hash模式,根路径是固定的,就是项目的根目录,但是history模式下,以 / 开头的嵌套路径会被当作根路径,所以使用“./”引入文件,就会找不到文件了,因为文件本身就是在项目根目录下的,并不在嵌套路径这个目录下。
总结,无论hash模式还是history模式,可以直接使用“/”从项目根目录引入静态文件。
原文链接:HelloWeb前端网 » 解决 vue 去掉#打包后页面空白路由出错等问题 » 感谢您的浏览,希望能有所帮助。
欢迎您加入“Helloweb” 学习交流群:
196291215 共同交流并结识同行,在这里说出您的收获与感想或有什么不同的观点,我们期待您的留言,分享,让我们一起进步!