问题背景
- Vue项目中使用了Vue-router作为路由来实现页面跳转,但是在浏览器url处却会有hash值显示,即我们看到的’#’符号,那么怎么去除这个难看的’#’,为了解决这个问题有了这篇文章
步骤
单页面应用
vue-router在创建router的时候将模式设置为history,如下,详见官方文档
1
const router = new VueRouter({
2
mode: 'history',
3
routes: [...]
4
})
此时即可去除掉讨人厌的’#’啦,但是接下来会产生问题:刷新页面后会显示404找不到页面。这是因为浏览器在发送请求的时候不会携带#后面的值,但是我们隐藏了#后使得hash值看起来像是url的一部分,浏览器根据这个url来请求当然找不到页面了。所以要对webpack和nginx进行一些配置
修改webpack.config.js文件,在output项中加上publicPath: ‘/‘,修改后如下。表示寻找资源的路径为根目录
1
output: {
2
publicPath: '/', // 新增
3
filename: 'bundle.js',
4
path: path.resolve(__dirname, 'dist') // 打包后文件生成的路径
5
},
在本地调试应用的时候,需要给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
},
在部署到服务器的时候,也是同样的原理设置nginx.cofig文件,使用try_files来表示用index.html替换掉找不到的uri
1
location / {
2
...
3
try_files $uri $uri/ /index.html;
4
}
多页面应用
对于多页面应用,我们希望能够实现访问
域名/A
可以去到A页面,域名/B
去到B页面,这时需要在设置vue-router的时候添加一个base属性。如果是A页面则base为A1
export default new VueRouter({
2
mode: "history",
3
base:"main",
4
...
5
})
在webpack.config.js设置打包生成的路径,最终生成的目录应该为
1
.
2
├── A
3
│ ├── index.html
4
│ └── index.js
5
└── B
6
├── index.html
7
└── index.js
为了在本地调试能够根据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
},
在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
}