# 1)新建项目并初始化 package.json

在你想放项目的目录执行:

mkdir vue-router-demo
cd vue-router-demo
npm init -y

说明:

  • npm init -y 会生成一个基本的 package.json,我们后面会往里面加脚本。

# 2)从你要求的那条开始:安装 Vue

npm install vue@latest

说明:

  • 这会把最新稳定版 Vue(通常是 Vue 3)装到 node_modules 并加入 package.jsondependencies

# 3)安装开发工具(Vite)与 Vue 插件

npm install -D vite @vitejs/plugin-vue

说明:

  • Vite 是现代前端开发工具:启动快、热模块替换(HMR)体验好;@vitejs/plugin-vue 让 Vite 能处理 .vue 单文件组件(SFC)。

# 4)安装 vue-router(Vue 3 对应 vue-router@4)

npm install vue-router@4

说明:

  • vue-router@4 与 Vue 3 配套,负责单页应用的路由管理(链接、路由钩子、动态路由等)。

# 5)在 package.json 添加常用脚本

编辑 package.jsonscripts 字段,加入:

"scripts": {
  "dev": "vite",
  "build": "vite build",
  "preview": "vite preview"
}

说明:

  • npm run dev:本地开发服务器(带 HMR)
  • npm run build:生产构建(打包)
  • npm run preview:本地预览打包输出(用于检查构建产物)

# 6)项目目录结构(我们要创建这些文件)

vue-router-demo/
├─ index.html
├─ package.json
├─ vite.config.js
└─ src/
   ├─ main.js
   ├─ App.vue
   ├─ router/
  │  └─ index.js
   └─ views/
      ├─ Home.vue
      ├─ About.vue
      └─ User.vue

下面逐个文件给出可复制的完整代码,并解释关键行。


# 7)创建 vite.config.js

// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [vue()]
})

说明:

  • 必须将 @vitejs/plugin-vue 注册为插件,Vite 才能识别 .vue

# 8)创建 index.html

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vue Router Demo</title>
  </head>
  <body>
    <div id="app"></div>
    <!-- vite 使用 module 脚本入口 -->
    <script type="module" src="/src/main.js"></script>
  </body>
</html>

说明:

  • Vite 要求在 HTML 中用 type="module" 引入入口文件(/src/main.js)。

# 9)创建 src/main.js(项目启动文件)

// src/main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router' // 会自动找 src/router/index.js

const app = createApp(App)
app.use(router)  // 把路由插件挂载到 Vue 应用
app.mount('#app')

解释:

  • createApp(App):创建 Vue 应用实例。
  • app.use(router):把 vue-router 注册为插件(这样组件内可以使用 <router-link><router-view>useRouter() 等)。
  • app.mount('#app'):把应用挂到 index.html 的 <div id="app">

# 10)创建路由文件 src/router/index.js

// src/router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import About from '../views/About.vue'
import User from '../views/User.vue'

const routes = [
  { path: '/', name: 'Home', component: Home },
  // 懒加载写法(可选):component: () => import('../views/About.vue')
  { path: '/about', name: 'About', component: About },
  // 动态路由: :id 是参数; props: true 会把 route.params 作为组件 props
  { path: '/user/:id', name: 'User', component: User, props: true }
]

const router = createRouter({
  history: createWebHistory(), // 使用 HTML5 history 模式
  routes
})

export default router

说明:

  • createWebHistory():产生“漂亮的”URL(无 #)。但部署到静态服务器时要确保服务器把所有请求回退到 index.html(否则刷新会 404)。如果你不能配置服务器,改用 createWebHashHistory(),URL 会带 #(例如 /#/about),无需服务器配置。

# 11)创建根组件 src/App.vue

<!-- src/App.vue -->
<template>
  <div>
    <nav>
      <router-link to="/">Home</router-link> |
      <router-link to="/about">About</router-link> |
      <router-link :to="{ name: 'User', params: { id: 123 } }">User 123</router-link>
    </nav>

    <hr />
    <!-- 路由视图:当前路由对应的组件会渲染到这里 -->
    <router-view />
  </div>
</template>

<style>
nav { padding: 1rem; }
.router-link-active { font-weight: bold; color: #42b983; }
</style>

说明:

  • <router-link>:替代 <a> 的路由链接组件,内部处理 push/replace 而不刷新页面。
  • <router-view>:路由占位符,渲染当前路由对应组件。
  • .router-link-active:路由激活时默认类名,可以用来高亮当前链接。

# 12)示例视图组件:Home.vue, About.vue, User.vue

src/views/Home.vue

<template>
  <div>
    <h1>Home</h1>
    <p>Welcome to the Vue + Router demo.</p>
    <button @click="goUser42">Go to User 42 (programmatic)</button>
  </div>
</template>

<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()
function goUser42() {
  // programmatic navigation
  router.push({ name: 'User', params: { id: 42 } })
}
</script>

src/views/About.vue

<template>
  <div>
    <h1>About</h1>
    <p>Simple about page.</p>
  </div>
</template>

src/views/User.vue

<template>
  <div>
    <h1>User page</h1>
    <p>User id: <!--swig0--></p>
    <button @click="$router.back()">Back</button>
  </div>
</template>

<script setup>
const props = defineProps({
  id: { type: [String, Number], required: true }
})
</script>

说明:

  • Home.vue 示范“编程式导航”(router.push({...}))。
  • User.vue 使用 props 接收路由参数(因为我们在路由配置里写了 props: true)。这样组件更容易测试、复用,不用在组件内部直接读 $route.params

# 13)运行开发服务器

在项目根运行:

npm run dev

会看到类似:

  vite vX.X.X  ready in 200ms
  Local: http://localhost:5173/

打开浏览器访问 http://localhost:5173(端口以实际启动日志为准)。点击导航链接、试试“Go to User 42”按钮,URL 与页面应同步变化且不会完整刷新。


# 14)打包与预览(生产构建)

npm run build
npm run preview
  • npm run build 生成静态文件(dist/)。
  • npm run preview 在本地起一个小服务器预览构建后的页面。

部署注意:

  • 如果使用 createWebHistory()(无 #),服务器必须配置:当用户请求 /about 时返回 index.html(single page app fallback)。例如 Nginx:

    location / {
      try_files $uri $uri/ /index.html;
    }
  • 不想配置服务器可使用 createWebHashHistory()


# 15)常见进阶点

  1. 懒加载路由(减小首包)

    { path: '/about', component: () => import('../views/About.vue') }

这样 About 会被拆成单独 chunk,只有访问时才加载。

  1. 路由守卫(路由拦截)

    router.beforeEach((to, from) => {
      if (to.meta.requiresAuth && !isLoggedIn()) return { name: 'Home' }
    })

to.meta 可以在路由配置时设置 meta: { requiresAuth: true }

  1. 嵌套路由(子路由)
  • 可用于 Dashboard 布局 + 子页面。
  • 在父组件里放 <router-view /> 作为子路由的渲染位置。
  1. 命名视图(多个 <router-view name="...">
  • 用于布局复杂页面(侧栏 + 主体同时切换不同组件)。
  1. useRoute / useRouter
  • const route = useRoute():读取路由信息(params、query、meta)。
  • const router = useRouter():编程式导航(push/replace)。