如何优雅的使用 Vue Router History 模式
如果不想要很丑的 hash,我们可以用路由的 history 模式,这种模式充分利用 history.pushState API 来完成 URL 跳转而无须重新加载页面。 —— Vue Router 官网为啥要使用 History 模式还能有什么原因,hash 模式的 # 不好看呗,当然了,我们也不能仅仅只看颜值,还有一些其他原因,例如 hash 模式下对一些需要锚点功能的需求会和他的路由...
如果不想要很丑的 hash,我们可以用路由的 history 模式,这种模式充分利用 history.pushState API 来完成 URL 跳转而无须重新加载页面。 —— Vue Router 官网
为啥要使用 History 模式
还能有什么原因,hash 模式的 # 不好看呗,当然了,我们也不能仅仅只看颜值,还有一些其他原因,例如 hash 模式下对一些需要锚点功能的需求会和他的路由机制有冲突,而相比于 hash 模式,hisitory 模式有以下几个点值得留意:
- 新的 URL 可以是与当前 URL 同源的任意 URL 。而设置 window.location 仅当你只修改了哈希值时才保持同一个 document。
- 设置的新 URL 可以与当前 URL 一模一样,这样也会把记录添加到栈中,而 hash 设置的新值必须与原来不一样才会触发动作将记录添加到栈中。
- 你可以为新的历史记录项关联任意数据。而基于哈希值的方式,则必须将所有相关数据编码到一个短字符串里。
- 可额外设置 title 属性供后续使用。
配置 History
说干就干,开始将我们项目的路由模式切换成 history 模式。
const router = new VueRouter({
mode: 'history',
routes: [...]
});
配置就是这么 easy,按道理,本篇文章到这也差不多可以结束了,但如果真的这么结束了,那我只能说 too young, too simple ,配置虽然简单,但切换后不仅需要后台的支持,还有一堆的坑等着你来踩呢。
后端配置
当我们在界面上点击刷新按钮的时候,会发现页面一片空白,这是为啥?打开控制台就会看到几个显眼的404,至于原因嘛,在官网上就有提到,History 这种模式要玩好,还需要后台配置支持。简单来讲就是,如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是我们 app 依赖的页面。
至于怎么配置,那就不是我们前端关心的事了,当然咯,作为励志成为爆栈工程师的我们,还是有必要了解一下这个配置过程,具体看官网就行,不行就 Google。
这里针对官网的内容补充一点就是,实际使用过程中,我们往往会将整个 dist 目录放到网站的根目录下,这时候就需要配置项目的 baseUrl。
- vue.config.js 中配置 publicPath
module.exports = {
publicPath: '/dist'
}
- 路由配置 base
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes: [...]
});
- 修改 nginx 配置
location / {
try_files $uri $uri/ /dist/index.html;
}
此时我们的访问路径就应该类似这样:http://localhost:8888/dist/home
有时候,我们可能需要 URL 的前缀不是 dist 而是 vue,当然也有可能想通过一个二级域名或者不带前缀的域名来访问,对于这样的需求,这里仅提供一种 nginx 反向代理的方案:
server {
listen 8887;
location / {
rewrite / /vue ;
}
location /vue {
proxy_pass http://localhost:8888/dist;
proxy_set_header Host $host:$server_port;
}
}
server {
listen 8888;
server_name localhost;
location / {
root html;
index index.html index.htm;
try_files $uri $uri/ /dist/index.html;
}
}
踩坑实录
如果只是上面提到的简单配置就能搞定,那这篇文章也没啥好写的,毕竟官网写的那么详细,既然写了,就说明,本人在从 hash 模式切换到 history 模式的过程中,除了配置之外,还有那么一丢丢可以聊一聊的故事。
Uncaught SyntaxError: Unexpected token <
项目用的脚手架 vue-cli 3,之前 hash 模式打包后,会出现找不到静态资源的情况,将 publicPath 修改为 ‘./’(默认是’/’),很凑巧,改成 history 模式后,会报错 Uncaught SyntaxError: Unexpected token < ,该问题产生原因跟我们之前 hash 模式下打包时配置的相对路径有关,将其改回绝对路径即可。
本地预览打包后的项目
hash 模式下,我们直接打包后,打开 dist 目录下的 index.html 文件就可以预览,但是 history 模式不行,那咋整呢?自己本地搭一个服务器,运行静态资源呗。
既然是前端开发,最熟悉的莫过于 Node 了,这里用 express 为例:
const express = require('express');
const app = express();
const PORT = 8081;
app.set('port', PORT);
app.use('/', express.static('./dist'));
app.listen(app.get('port'), () => {
console.log('Server Running');
});
启动服务器即可访问,既然是 history 模式,就不可避免的会存在我们前文提到的刷新后界面空白问题,所以我们还需要做一个重定向处理。
const history = require('connect-history-api-fallback');
app.use(history());
这样就完了吗?还不够!因为之前开发环境是通过配置 devServer.proxy 来请求后端接口,所以我们还需要加一个反向代理。
const HOST = 'http://xx.xxx.xx.xx:xx';
app.use(proxy('/xxx', {
target: HOST
}));
然后重启服务,预览效果,破菲特!
总结
啰嗦了这么多,其实总结起来就是一句话,看官方文档,官方文档不够就 Google 来凑!
更多推荐
所有评论(0)