Vue3路由与Vite的base

前端

虽然我不是一个专门搞前端的,但也会写点点 Vue。最近实验室项目写完后需要部署一下,这里我就使用了 Docker Compose 来部署。由于前端项目有前台用户端访问和后台管理端两个,而老师申请的服务器只开了 80 端口,因此我就打算使用 nginx 来反向代理:

  • http://example.com 为前台
  • http://example.com/admin 为后台

ok,那我就用了一个 nginx 容器做网关,其 nginx.conf 如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
server {
	listen 80;
	listen [::]:80;
	
	server_name _;
	
	# 后台管理
	location /admin/ {
		proxy_pass http://frontend-admin;
		proxy_set_header Host $host;
		proxy_set_header X-Real-IP $remote_addr;
	} 
	
	# 后端接口
	location /api {
		proxy_pass http://backend:8080/;
		proxy_set_header Host $host;
		proxy_set_header X-Real-IP $remote_addr;
	}
	
	# minio
	location /images/ {
		proxy_pass http://minio:9000/;
		proxy_set_header Host $host;
		proxy_set_header X-Real-IP $remote_addr;
	}
	
	# 前台用户
	location / {
		proxy_pass http://frontend-user/;
		proxy_set_header Host $host;
		proxy_set_header X-Real-IP $remote_addr;
	}
	
	location = /admin {
		return 301 /admin/;
	}
}

docker compose up -d 后,用户端能访问并且接口没问题,但是一到管理端 http://xx.xx.xx.xx/admin,就会是白屏,我检查了一下,管理端页面的标签栏标题是正确的,也就是 nginx 反向代理没问题,获取的 index-xxx.js 和 index-yyy.css 也没问题,那就奇了个怪了。

研究了一番才发现,修改了 base 配置后,创建路由时也需要使用 BASE_URL(或等效值)的原因是为了保证前端路由与部署路径的一致性。而我在 vite.config.js 中的 base 如下:

1
2
3
export default defineConfig({
  base: '/admin/',
})

vite.config.js 中设置的 base 选项,表示:

  • 所有静态资源(JS、CSS、图片等)的公共基础路径;
  • 构建后的 HTML 文件中引用资源时会自动加上这个前缀;

构建后,所有资源路径会变成 /admin/assets/xxx.js

Vue Router 默认假设应用部署在域名根路径(即 /)。如果你把应用部署在子路径下(如 https://example.com/admin/),而路由仍以 / 为基准,就会出现:

  • 页面刷新后 404;
  • 路由跳转错误或无法匹配。

因此,Vue Router 需要知道“应用实际挂载的路径前缀”,这就是 history 配置中的 base 参数。


在 Vite 项目中,import.meta.env.BASE_URL 是一个由 Vite 自动注入的变量,它的值就是 vite.config.js 中配置的 base

所以,在创建路由时这样写:

1
2
3
4
5
6
7
// router/index.js
import { createRouter, createWebHistory } from 'vue-router'

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [...]
})

这样就能确保:

  • 开发环境(base: '/')和生产环境(base: '/admin/')使用相同的代码;
  • 路由前缀与静态资源前缀保持一致;
  • 避免部署到子目录时出现空白页或路由错乱。
Licensed under CC BY-NC-SA 4.0
使用 Hugo 构建
主题 StackJimmy 设计