解决 vue 去掉#打包后页面空白路由出错等问题

vue helloweb 次浏览 已收录 评论() 扫描二维码
扫描二维码

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” 学习交流群:HelloWeb-学习交流群 196291215 共同交流并结识同行,在这里说出您的收获与感想或有什么不同的观点,我们期待您的留言,分享,让我们一起进步!

喜欢 ()or分享