createrouter 必须显式传入 history 实例,如 createwebhistory() 或 createwebhashhistory();路由组件懒加载需写为 () => import(...);需在 main.js 中通过 app.use(router) 安装且置于 app.mount() 前。

vue-router@4 的 createRouter 必须配 history 实例
Vue 3 项目里直接 createRouter({ routes }) 会报错,因为缺少 history 参数。错误信息通常是 "TypeError: Cannot read properties of undefined (reading 'pushState')" 或直接白屏无提示。
必须显式传入一个 history 实例,最常用的是 createWebHistory()(对应 HTML5 history 模式)或 createWebHashHistory()(兼容老浏览器,URL 带 #)。
-
createWebHistory():部署时需后端配合,否则刷新 404;开发期默认可用 -
createWebHashHistory():无需服务端配置,但 URL 不够美观,如/#/login - 别用
createMemoryHistory()——它只适用于测试或非浏览器环境(比如 SSR 渲染器),在普通浏览器中无法触发地址栏变化
路由组件懒加载要写成函数调用形式
写成 component: import('@/views/HomeView.vue') 是错的,这返回的是 Promise,createRouter 会直接报类型错误;正确写法是包裹成异步函数:component: () => import('@/views/HomeView.vue')。
这种写法不仅语法合法,还让 Webpack/Vite 能自动做代码分割,首屏体积更小。
- 如果组件路径拼错(比如
@/views/homeView.vue写成小写homeview),开发服务器不会报错,但页面空白,控制台也无明显提示——检查import()路径是否与文件系统大小写完全一致 - 不建议在路由配置里直接写
defineAsyncComponent,冗余且破坏可读性;() => import(...)就是 Vue 官方推荐的懒加载标准写法
VSCode 中快速生成 router/index.js 模板的实操技巧
不用每次手动敲 import、routes、createRouter……VSCode 可以用代码片段(snippets)秒建基础结构。
在用户代码片段中(Ctrl+Shift+P → Preferences: Configure User Snippets → vue),添加:
递归分析 Vue 项目组件依赖,从入口文件生成组件层级图,支持 Vue 2/3,输出组件名、文件路径和属性。适用于分析组件结构、排查依赖或了解项目架构。
"Vue Router Setup": {
"prefix": "vrouter",
"body": [
"import { createRouter, createWebHistory } from 'vue-router'",
"",
"const routes = [",
" { path: '/', name: 'Home', component: () => import('@/views/HomeView.vue') },",
" { path: '/login', name: 'Login', component: () => import('@/views/LoginView.vue') }",
"]",
"",
"const router = createRouter({",
" history: createWebHistory(),",
" routes",
"})",
"",
"export default router"
]
}
之后在 src/router/index.js 中输入 vrouter + Tab,就自动生成骨架。路径和组件名按需替换即可,省去重复劳动。
注意:这个片段默认用了 createWebHistory(),如果你项目用 hash 模式,记得手动改成 createWebHashHistory()。
main.js 中 use(router) 不能漏掉 app.use()
Vue 3 的组合式 API 入口不再用 new Vue({ router }),而是通过 app.use(router) 显式安装插件。漏掉这句,<router-view></router-view> 渲染为空,<router-link></router-link> 点击无反应,控制台也几乎不报错——这是最隐蔽也最常踩的坑。
正确写法(以 Vite 默认 main.js 为例):
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
const app = createApp(App)
app.use(router) // ← 这行不能少
app.mount('#app')
另外,app.use(router) 必须在 app.mount() 之前调用,顺序颠倒会导致路由实例未被注入,所有导航逻辑失效。
复杂点在于:如果你在 main.js 里做了插件链式注册(比如同时用 Pinia、i18n),router 的位置没有硬性要求,但必须确保它在 mount 前完成注册——这点容易被忽略,尤其当代码被多人协作拆分时。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










