在 Vue 3 的生态系统中,Vue RouterPinia 是两大核心支柱。简单来说:Vue Router 负责“去哪儿”(页面跳转与路由控制),而 Pinia 负责“带点啥”(全局状态/数据的跨组件共享)。

下面为你拆解它们的作用以及在 Vue 3(组合式 API + Vite)中的具体使用步骤。

一、 Vue Router (路由管理器)

匹配成功

匹配失败

路由守卫流程

通过

拒绝

进入路由前
beforeEach

权限验证

继续导航

重定向或取消

用户点击导航链接

Vue Router 拦截请求

路由匹配检查

加载对应组件

显示404页面

渲染到 router-view

更新浏览器URL

页面切换完成
无整页刷新

1. 作用

  • 单页面应用 (SPA) 路由控制:在不刷新整个页面的情况下,切换组件实现“换页”。

  • 路由守卫:实现登录拦截、权限验证等功能。

  • 传参机制:支持动态路由传参(如 /user/:id)和查询参数(如 /search?keyword=abc)。

2. 具体使用步骤

步骤 1:安装

如果你在创建 Vite 项目时没有勾选,可以手动安装,下载Vue Router 4.x.x 最新稳定版:

npm install vue-router@4
步骤 2:创建路由配置文件

src 目录下新建 router/index.ts

import HomeView from "../views/HomeView.vue";  
import {createRouter, createWebHistory} from "vue-router";  
  
  
// 1. 引入组件  
const routes = [  
     {  
         path: '/',  
         name: 'home',  
         component: HomeView  
     },  
     {  
         path: '/about',  
         name: 'about',  
         component: () => import('@/views/AboutView.vue')  
     },  
    {  
        path: '/my',  
        name: 'my',  
        component: () => import('@/views/MyView.vue')  
    }  
 ]  
  
// 2. 创建路由实例并传递 `routes` 配置  
const router = createRouter({  
    history: createWebHistory(),  
    routes  
})  
  
export default router
步骤 3:在 main.ts 中挂载
import { createApp } from 'vue'
import App from './App.vue'
import router from './router' // 引入路由

const app = createApp(App)

app.use(router) // 注册路由
app.mount('#app')
步骤 4:在组件中使用(视图出口与跳转)

App.vue 中放置占位符:

<template>  
  <header>    
    <router-link to="/">首页</router-link> |  
    <router-link to="/about">关于</router-link> |  
    <router-link to="/my">我的</router-link>  
  </header>  
  <hr>  
  <main>    
	  <router-view />  
  </main>  
</template>

如果你想在 JS/TS 脚本中做编程式导航跳转:

<template>  
  <header>    
    <button @click="goToHome">首页</button>  
    <button @click="goToAbout">关于</button>  
    <button @click="goToMy">我的</button>  
  </header>  
  <hr>  
  <main>    
	  <router-view />  
  </main>  
</template>
步骤五:创建组件

src/views/ 下建立对应组件:

HomeView.vue

<script setup>  
  
</script>  
  
<template>  
  <div class="home">  
    <h1>Welcome to the Home Page</h1>  
    <p>This is the main landing page of the application.</p>  
  </div></template>  
  
<style scoped>  
  
</style>

AboutView.vue

<script setup>  
  
</script>  
  
<template>  
  <div class="about">  
    <h1>About This Application</h1>  
    <p>This application is built using Vue.js and demonstrates basic routing and navigation.</p>  
  </div></template>  
  
<style scoped>  
  
</style>

Myview.vue

<script setup>  
  
</script>  
  
<template>  
  <div class="about">  
    <h1>About This Application</h1>  
    <p>This application is built using Vue.js and demonstrates basic routing and navigation.</p>  
  </div></template>  
  
<style scoped>  
  
</style>

效果展示

通过观察导航栏的变化,可以知道路由已经实现。

![[VueRouter_1.png]]

![[VueRouter_2.png]]

![[VueRouter_3.png]]

二、 Pinia (新一代状态管理库)

Pinia Store 仓库

读取/修改

读取/修改

读取/修改

State
响应式数据

Getters
计算属性

Actions
操作方法

组件A

组件B

组件C

传统Props/Emit

父子组件传值
层级深时复杂

跨组件共享
直接访问

1. 作用

  • 全局状态共享:传统父子组件传值(Props/Emit)在跨层级多组件时很痛苦,Pinia 提供了一个公共“仓库”,任何组件都能直接读写它。

  • 替代 Vuex:比 Vuex 更轻量,完美支持 Vue 3 的 Composition API,且天然具备极好的 TypeScript 支持。

2. 具体使用步骤

步骤 1:安装
npm install pinia
步骤 2:在 main.js 中注册
import { createApp } from 'vue'
import { createPinia } from 'pinia' // 引入 Pinia
import App from './App.vue'

const app = createApp(App)
const pinia = createPinia()

app.use(pinia) // 注册 Pinia
app.mount('#app')
步骤 3:定义 Store (仓库)

src 下新建 store/counter.js。推荐使用更符合 Vue 3 习惯的 Setup Store 写法:

import { defineStore } from 'pinia'
import { ref, computed } from 'vue'

export const useCounterStore = defineStore('counter', () => {
  // 1. state: 定义响应式数据
  const count = ref(0)

  // 2. getters: 定义计算属性
  const doubleCount = computed(() => count.value * 2)

  // 3. actions: 定义修改数据的方法(支持同步和异步)
  function increment() {
    count.value++
  }

  // 记得把需要暴露的属性和方法 return 出来
  return { count, doubleCount, increment }
})
步骤 4:在组件中使用 Store
<script setup>
import { useCounterStore } from '../store/counter'
import { storeToRefs } from 'pinia'

// 1. 实例化 store
const counterStore = useCounterStore()

// 2. 注意:直接解构会破坏响应式!需要使用 storeToRefs
const { count, doubleCount } = storeToRefs(counterStore)

// 3. 方法可以直接解构,不需要 storeToRefs
const { increment } = counterStore
</script>

<template>
  <div>
    <p>当前计数: {{ count }}</p>
    <p>翻倍计数: {{ doubleCount }}</p>
    
    <button @click="increment">加 1</button>
    
    <button @click="counterStore.count++">行内加 1</button>
  </div>
</template>

Vue Router 与 Pinia 协同工作

权限控制场景

有权限

无权限

路由守卫
beforeEach

检查Pinia中
用户权限状态

允许进入

重定向到登录页

数据流与状态管理

Pinia Store
全局状态

组件读取状态

用户交互

组件调用Action

更新Store状态

所有相关组件
自动更新

用户访问页面

Vue Router
路由匹配

加载对应组件

组件初始化

💡 总结与黄金法则

  • Vue Router 负责结构与路径。当你的应用有多个页面、需要做登录拦截(路由守卫)时,找它。

  • Pinia 负责数据与状态。当多个组件(不管是父子还是远房亲戚)需要共享同一份数据(如:当前登录的用户信息、购物车列表)时,找它。

  • 强强联合:在实际开发中,你甚至可以在 Vue Router 的路由守卫里直接引入 Pinia 的 Store,用来判断当前用户是否有权限访问某个页面。

更多推荐