问题背景

  • Vue项目中使用了Vue-router作为路由来实现页面跳转,但是在浏览器url处却会有hash值显示,即我们看到的’#’符号,那么怎么去除这个难看的’#’,为了解决这个问题有了这篇文章

步骤

单页面应用

  1. vue-router在创建router的时候将模式设置为history,如下,详见官方文档

    1
    const router = new VueRouter({
    2
        mode: 'history',
    3
        routes: [...]
    4
    })
  2. 此时即可去除掉讨人厌的’#’啦,但是接下来会产生问题:刷新页面后会显示404找不到页面。这是因为浏览器在发送请求的时候不会携带#后面的值,但是我们隐藏了#后使得hash值看起来像是url的一部分,浏览器根据这个url来请求当然找不到页面了。所以要对webpack和nginx进行一些配置

  3. 修改webpack.config.js文件,在output项中加上publicPath: ‘/‘,修改后如下。表示寻找资源的路径为根目录

    1
    output: {
    2
        publicPath: '/', // 新增
    3
        filename: 'bundle.js',
    4
        path: path.resolve(__dirname, 'dist')   // 打包后文件生成的路径
    5
    },
  4. 在本地调试应用的时候,需要给webpack.config.js中的devServer项加上一个配置项historyApiFallback。这个选项表示为如果路由页面找不到的话要怎么处理,此处表示为若找不到页面则加载index.html。此时上面设置的publicPath就起作用了,因为寻找文件是根据相对publicPath的路径来找的,如果没有设置则会把当前hash当成publicPath,就会产生找不到index.html的问题

    1
    devServer: {
    2
        historyApiFallback: {
    3
            index: '/index.html' //与output的publicPath有关(HTMLplugin生成的html默认为index.html)
    4
        }
    5
    },
  5. 在部署到服务器的时候,也是同样的原理设置nginx.cofig文件,使用try_files来表示用index.html替换掉找不到的uri

    1
    location / {
    2
            ...
    3
            try_files $uri $uri/ /index.html;
    4
        }

多页面应用

  1. 对于多页面应用,我们希望能够实现访问 域名/A可以去到A页面, 域名/B去到B页面,这时需要在设置vue-router的时候添加一个base属性。如果是A页面则base为A

    1
    export default new VueRouter({
    2
        mode: "history",
    3
        base:"main",
    4
        ...
    5
    })
  2. 在webpack.config.js设置打包生成的路径,最终生成的目录应该为

    1
    .
    2
    ├── A
    3
    │   ├── index.html
    4
    │   └── index.js
    5
    └── B
    6
        ├── index.html
    7
        └── index.js
  3. 为了在本地调试能够根据url值跳转到对应的页面,可以使用webpack devServer的historyApiFallback。注意to的值必须以/开头,否则无效。同样需要加上publicPath,此处不再赘述

    1
    devServer: {
    2
        historyApiFallback: {
    3
            rewrites: [
    4
                { from: /^\/main/, to: '/main/main.html' },
    5
                { from: /./, to: '/index/index.html' }
    6
            ],
    7
        },
    8
    },
  4. 在nginx的配置路由。修改nginx.conf文件

    1
    server{
    2
        ...
    3
        root /root/test/;
    4
    5
        location /A {
    6
            index index.html;
    7
            try_files $uri $uri/ /A/index.html;
    8
        }
    9
    10
        location /B {
    11
            index index.html;
    12
            try_files $uri $uri/ /B/index.html;
    13
        }
    14
    }

自此就配置完成了,但是这个方法还有一个小问题就是,无论输入什么样的路由,都不会出现404页面,都会重定向到index.html页面。所以需要在router的路由规则加多一条{ path: '*', component: NotFoundComponent },具体官方文档写得很清楚了,这里就不一一赘述