现代前端开发工程化:从 Vite 到 Vue 3 路由实战

在现代 Web 开发中,"工程化"已成为提升开发效率、保障项目质量的关键。本文将围绕 Vite 构建工具Vue 3 路由系统(vue-router) 以及 项目入口机制,带你快速搭建一个结构清晰、可维护性强的前端项目,并深入解析其背后的工程化思想。


结论先行:# 在 Hash 路由中的真实作用

# 的核心作用并非 "唯一性",而是作为「URL 锚点标识符」,实现前端路由的核心逻辑:隔离哈希值与服务器请求、前端独立控制路由。

一、# 的本质:URL 中的「哈希 / 锚点」

在 URL 中,# 是官方定义的 片段标识符(Fragment Identifier) ,具有以下特性:

  • 浏览器行为# 及其后的内容(哈希值)不会被发送到服务器,仅在浏览器端生效;
  • 锚点原生作用 :原本用于定位页面内的锚点(如 <a href="#top"> 跳转到页面顶部);
  • Hash 路由的复用 :前端路由框架(Vue Router、React Router)复用这一特性 ,将 # 后的内容作为 "前端路由路径",实现无刷新页面跳转。

二、# 的核心作用(与 "唯一性" 无关)

1. 隔离前端路由与服务器请求(核心价值)

例如 URL:http://localhost:5173/#/about

  • 浏览器向服务器发送请求时,只传递 http://localhost:5173/#/about 被忽略;
  • 服务器只需处理根路径,无需关心前端路由
  • 这解决了 单页应用(SPA)刷新 404 的问题------这是 Hash 路由最核心的价值,与"唯一性"完全无关

2. 前端独立控制路由状态

  • # 后的哈希值变化会触发浏览器的 hashchange 事件(不会刷新页面);
  • 框架监听该事件,根据哈希值匹配路由规则,渲染不同组件(如 /about → 渲染 About 组件);
  • 哈希值可自由修改(如 location.hash = '/home'),是前端路由的 "载体" ,而非 "唯一标识"。

3. 附带:可作为页面状态标识(非唯一性)

  • 哈希值可用于标记业务状态(如 #/article/123 标识文章 ID);
  • 但这属于 业务层面的标识# 本身只是承载容器;
  • 哈希值可重复 (比如不同页面手动设为相同 #/test),浏览器不限制。

三、为什么 "唯一性" 是错误认知?

  • # 是 URL 的固定语法符号 ,不是"唯一标识符":所有 Hash 路由都包含 #,它是统一的分隔符;
  • 哈希值本身也不保证唯一:你可以手动设置多个页面为相同哈希;
  • 唯一性需业务层面保证 :通过路由规则配置(如 /about/home 不重复)实现,与 # 无关。

四、Hash 路由 vs History 路由(对比理解 # 的作用)

特性 Hash 模式(带 # History 模式(无 #
服务器请求 仅发送 # 前的路径 发送完整路径
刷新 404 问题 (服务器只需处理根路径) 需服务器配置 (重定向到 index.html
兼容性 更好(支持低版本浏览器) 依赖 HTML5 History API
URL 美观性 #,相对不美观 #,更接近原生 URL

总结# 在 Hash 路由中的核心价值是------利用浏览器对 URL 哈希的原生处理规则,实现前端无刷新路由,同时避免前端路由路径被发送到服务器 。它是 "分隔符 / 载体" ,而非用于保证唯一性的标识。


一、为什么选择 Vite?

Vite 是由 Vue 作者尤雨溪开发的新一代前端构建工具,核心优势在于 极速冷启动即时热更新(HMR)

✨ 核心原理

  • 利用现代浏览器原生支持的 ES 模块(ESM) ,无需打包即可直接加载模块。
  • 开发阶段:按需编译,只处理当前请求的文件,启动速度极快。
  • 生产环境:使用 Rollup 打包,兼顾性能与兼容性。

🚀 快速初始化项目

perl 复制代码
bash
编辑
npm create vite@latest my-vue-app -- --template vue
cd my-vue-app
npm install
npm run dev

此时,Vite 会:

  • 自动打开浏览器(如 http://localhost:5173
  • 监听 src/ 下所有文件变更,实现 毫秒级热更新
  • index.html 为入口,挂载到 <div id="app"></div>

二、标准项目结构解析

Vite + Vue 3 提供了高度规范化的目录结构:

csharp 复制代码
text
编辑
my-vue-app/
├── index.html               # 应用入口 HTML
├── src/
│   ├── main.js              # 应用入口 JS
│   ├── App.vue              # 根组件
│   ├── style.css            # 全局样式
│   ├── components/          # 可复用组件
│   └── views/               # 页面级组件(路由页面)
├── public/                  # 静态资源(不参与构建)
└── package.json             # 依赖与脚本管理

💡 关键点main.js 中通过 createApp(App).mount('#app') 将 Vue 应用挂载到 DOM。


三、多页面应用:集成 Vue Router

单页应用(SPA)需要路由来切换不同"页面"。Vue 官方推荐使用 vue-router

第一步:先看整体结构(总览)

这段代码是 Vue 项目中「路由配置文件」(src/router/index.js),核心分为 4 个部分

  1. 导入 Vue Router 核心方法 + 页面组件
  2. 定义「路由规则数组」(URL 对应哪个组件);
  3. 创建「路由实例」(把规则和路由模式结合);
  4. 导出路由实例 (让项目入口文件 main.js 能使用)。

下面先看完整代码标注:

javascript 复制代码
js
编辑
// 1. 导入依赖:从 vue-router 库中拿需要的工具函数
import { createRouter, createWebHashHistory } from 'vue-router'
// 2. 导入页面组件:从 views 目录导入 Home/About 组件(就是你要显示的页面)
import Home from '../views/Home.vue'
import About from '../views/About.vue'

// 3. 定义路由规则:数组里每一个对象就是一条「URL → 组件」的规则
const routes = [
  { path: '/', name: 'Home', component: Home }, // 访问根路径 → 显示 Home 组件
  { path: '/about', name: 'About', component: About } // 访问 /about → 显示 About 组件
]

// 4. 创建路由实例:把规则和路由模式(# 模式)结合,生成可使用的路由对象
const router = createRouter({
  history: createWebHashHistory(), // 路由模式:Hash 模式(URL 带 #)
  routes // 把上面定义的规则数组传给路由实例
})

// 5. 导出路由实例:让 main.js 能导入并挂载到 Vue 应用上
export default router

第二步:逐行拆解(零基础也能懂)

1. 导入部分:拿工具 + 拿组件

javascript 复制代码
js
编辑
// 从 vue-router 库中导入两个核心函数:createRouter、createWebHashHistory
import { createRouter, createWebHashHistory } from 'vue-router'
  • createRouter:创建路由实例的 "工厂函数" ------ 你可以理解为 "造路由的模具",调用它就能生成一个能工作的路由对象;
  • createWebHashHistory:路由模式的 "生成器" ------ 专门生成「Hash 模式」的路由历史(URL 带 #,比如 http://localhost:5173/#/about);

🔍 补充 :Vue Router 还有另一种模式 createWebHistory()(History 模式,URL 不带 #,比如 http://localhost:5173/about),但需要后端配置,新手建议先用 Hash 模式。

javascript 复制代码
js
编辑
// 导入页面组件:../ 表示"上一级目录",即从 router 目录回到 src 目录,再进 views 目录拿组件
import Home from '../views/Home.vue'
import About from '../views/About.vue'
  • ../views/Home.vue 路径含义(新手重点):

    • 当前文件在 src/router/index.js../ 是 "跳出 router 目录",回到 src 目录;
    • 然后进入 views 目录,找到 Home.vue 文件(就是你写的首页组件);
  • 作用:把页面组件 "拿进来",让路由规则能关联到它。


2. 定义路由规则数组:const routes = [...]

ini 复制代码
js
编辑
const routes = [
  { path: '/', name: 'Home', component: Home },
  { path: '/about', name: 'About', component: About }
]

这是核心规则:数组里的每个对象对应「一个 URL 路径 → 一个页面组件」,每个对象的 3 个核心属性:

属性 含义
path 访问的 URL 路径(必填) : -- / 表示 "根路径"(如 http://localhost:5173/#/) -- /about 表示 "/about 路径"(如 http://localhost:5173/#/about
name 路由的 "别名"(可选,但推荐加) : 后续可以用 router.push({ name: 'About' }) 跳转,比写路径更灵活,便于后期维护
component 路径对应的页面组件(必填) : 就是你前面导入的 Home/About 组件,访问该路径时,页面就会渲染这个组件

3. 创建路由实例:const router = createRouter({...})

scss 复制代码
js
编辑
const router = createRouter({
  history: createWebHashHistory(), // 路由模式
  routes // 等价于 routes: routes(ES6 简写)
})
  • createRouter():调用第一步导入的 "造路由模具",传入配置对象,生成一个「路由实例」(可以理解为 "能工作的路由器");

  • history: createWebHashHistory():指定路由的「历史模式」为 Hash 模式,核心特点:

    • URL 中会带 #(比如 #/about),# 后面的内容不会发送到后端;
    • 所以不需要后端配置(新手友好);
    • 例如访问 http://localhost:5173/#/about,浏览器只会把 http://localhost:5173/ 发给服务器,#/about 由前端路由处理;
  • routes:把前面定义的规则数组传给路由实例,告诉路由器 "该怎么匹配 URL 和组件"。


4. 导出路由实例:export default router

arduino 复制代码
js
编辑
export default router
  • 作用 :把创建好的路由实例 "暴露出去",让项目的入口文件(src/main.js)能导入并挂载到 Vue 应用上;
  • 类比:就像你造好了一个 "路由器",现在把它拿出来,让整个 Vue 项目能使用这个路由器。

第三步:这个文件的 "配套操作"(必须知道,否则路由不生效)

光写路由配置文件还不够!必须完成以下两步,路由才能真正工作:

1. 在 main.js 中挂载路由

main.js 是 Vue 3 项目的入口文件(程序启动的第一个文件) ,负责创建 Vue 应用实例、配置插件、挂载到页面。

逐行拆解如下:

javascript 复制代码
js
编辑
// 1. import { createApp } from 'vue'
// 从 Vue 核心库导入 createApp 函数(创建应用的"工厂")
// Vue 3 不再用 new Vue(),而是用 createApp 创建独立实例(支持多应用)
import { createApp } from 'vue'

// 2. import App from './App.vue'
// 导入根组件 App.vue ------ 整个应用的"容器"
// 所有页面/组件最终都嵌套在 App.vue 内
import App from './App.vue'

// 3. import router from './router'
// 导入路由实例(来自 src/router/index.js)
// ./router 会被自动识别为 ./router/index.js
import router from './router'

// 4. import './style.css'
// 导入全局样式,作用于整个应用
import './style.css'

// 5. 链式调用:创建 → 注册 → 挂载
createApp(App)
  .use(router)     // 注册路由插件(启用 <router-link>、<router-view> 等功能)
  .mount('#app')   // 挂载到 HTML 中的 <div id="app"></div>

💡 链式调用等价写法(更易理解)

scss 复制代码
js
编辑
const app = createApp(App)
app.use(router)
app.mount('#app')
关键概念补充:
  • 为什么是 main.js
    Vite/Vue CLI 默认将其作为打包入口,最先执行。
  • 模块化(import/export)
    router/index.jsexport default router,所以这里能 import router
  • 单页应用(SPA)
    整个项目只有一个 HTML 文件(public/index.html),页面跳转靠路由实现,不刷新。

一句话总结 main.js 的作用
导入 Vue 核心工具、根组件、路由和全局样式 → 创建 Vue 应用实例 → 注册路由插件 → 把应用挂载到页面的 #app 元素上,最终启动整个 Vue 应用。


2. 在 App.vue 中添加路由出口

.vue 文件是 Vue 特有的单文件组件格式,一个文件就是一个独立组件,包含三部分:

  • <template>:结构
  • <script>:逻辑
  • <style>:样式
xml 复制代码
vue
编辑
<!-- src/App.vue -->
<template>
  <div>
    <!-- 头部导航 -->
    <header>
      <nav>
        <ul>
          <!-- Vue 路由链接:点击不刷新页面 -->
          <li><router-link to="/">Home</router-link></li>
          <li><router-link to="/about">About</router-link></li>
        </ul>
      </nav>
    </header>
    
    <!-- 主内容区 -->
    <main>
      <!-- 路由出口:页面组件在此动态渲染 -->
      <router-view />
    </main>
  </div>
</template>

<style scoped>
/* scoped 样式仅作用于当前组件 */
ul { display: flex; gap: 16px; list-style: none; }
</style>
核心标签解释:
标签 作用
<router-link to="..."> 替代 <a> 的路由导航组件 点击不刷新页面,仅替换 <router-view> 内容
<router-view /> 路由出口(占位符) 访问 / 时显示 Home 组件,访问 /about 时显示 About 组件

运行逻辑

  1. 访问 http://localhost:5173/#/ → 匹配 path: '/' → 渲染 Home<router-view>
  2. 点击 "About" → URL 变为 #/about → 触发 hashchange → 渲染 About 组件
    全程无刷新 ,因为 # 后内容由前端处理。

第四步:运行逻辑(新手必懂)

当你启动项目(npm run dev)后,整个路由的工作流程如下:

  1. 浏览器访问 http://localhost:5173/#/
    → 路由实例匹配到 path: '/' 的规则
    → 把 Home 组件渲染到 App.vue<router-view> 位置
    → 页面显示首页;
  2. 点击 <router-link to="/about">
    → URL 变成 http://localhost:5173/#/about
    → 路由实例匹配到 path: '/about' 的规则
    → 把 About 组件渲染到 <router-view>
    → 页面切换为关于页;

全程页面不会刷新 (前端路由的核心优势),因为 # 后面的路径由前端处理,不请求后端。


第五步:新手常见疑问解答

❓ 为什么用 createWebHashHistory() 而不是 createWebHistory()

对比项 Hash 模式(# History 模式(无 #
URL 美观度 ❌ 有 # ✅ 干净路径
部署复杂度 ✅ 任意静态服务器 ❌ 需配置 fallback(如 Nginx 重定向到 index.html
兼容性 ✅ 所有浏览器 ✅ 现代浏览器(IE 不支持)

📌 建议 :初学者或静态站点用 Hash 模式 ;生产级 SPA 推荐 History 模式 + 服务端支持

name: 'Home' 有什么用?

除了通过路径跳转(router.push('/about')),还能通过名称跳转:

php 复制代码
js
编辑
// 更灵活!后续如果修改 path(比如把 /about 改成 /about-us),
// 只需改路由规则里的 path,不用改所有跳转代码
router.push({ name: 'About' })

❓ 组件必须放在 views 目录吗?

不是强制的views 是约定俗成的 "页面级组件" 目录(区别于 components/ 中的功能组件),你也可以用 pages/,只要导入路径对应即可。


四、开发体验增强工具

工具 作用
Volar(VS Code 插件) 提供 Vue 3 的语法高亮、智能提示、类型检查
Vue DevTools(浏览器插件) 调试组件状态、路由、Pinia/Vuex 等

⚠️ 注意:禁用旧版 Vetur,避免与 Volar 冲突。


五、总结要点

模块 关键知识点
Vite 基于 ESM 的极速开发服务器,无需打包即可运行
# 的作用 URL 哈希标识符,隔离前端路由与服务器请求,实现无刷新跳转
路由配置 定义 path → component 规则,创建 Hash 模式路由实例
main.js 创建应用 → 注册路由 → 挂载到 #app,启动整个 SPA
App.vue 使用 <router-link> 导航 + <router-view> 渲染页面
工程化思维 组件化、模块化、关注点分离(页面 vs 功能组件)

💬 一句话记住路由核心

这段代码的作用是:创建一个 "Hash 模式" 的路由实例,定义了「根路径显示 Home 组件、/about 路径显示 About 组件」的规则,最后导出这个实例,让整个 Vue 应用能根据 URL 切换页面组件。


六、注意事项

  1. 路径别名 :Vite 默认不支持 @ 别名,需手动配置 vite.config.js

    javascript 复制代码
    js
    编辑
    import { defineConfig } from 'vite'
    import vue from '@vitejs/plugin-vue'
    import { resolve } from 'path'
    
    export default defineConfig({
      plugins: [vue()],
      resolve: {
        alias: {
          '@': resolve(__dirname, 'src')
        }
      }
    })
  2. 热更新失效? 检查是否修改了非 .vue/.js 文件(如 vite.config.js 需重启)。

  3. TypeScript 支持 :Vite 原生支持,初始化时选择 vue-ts 模板即可。


结语

从前端"写页面"到"构建工程",Vite + Vue 3 + vue-router 的组合提供了开箱即用的现代化开发体验。掌握这套工具链,不仅能提升开发效率,更是迈向专业前端工程师的重要一步。

相关推荐
老华带你飞3 小时前
健身房预约|基于springboot 健身房预约小程序系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·小程序
paopaokaka_luck3 小时前
基于SpringBoot+Uniapp的自习室预约小程序(腾讯地图API、Echarts图形化分析、二维码识别)
vue.js·spring boot·后端·spring·echarts
博客zhu虎康3 小时前
Vue全局挂载Element消息组件技巧
前端·javascript·vue.js
神秘的猪头3 小时前
# Vue项目初识:从零开始搭建你的第一个现代前端工程化Vue3项目
前端·vue.js·面试
叫我詹躲躲3 小时前
vue3插槽的本质
vue.js
黄老五3 小时前
createContext
前端·javascript·vue.js
q_19132846953 小时前
基于SpringBoot2+Vue2的装修报价网站
java·vue.js·spring boot·mysql·计算机毕业设计·演示文稿
YaeZed3 小时前
Vue3-动态组件
前端·vue.js
鹏多多4 小时前
前端项目package.json与package-lock.json的详细指南
前端·vue.js·react.js