Vue 进阶学习
本文最后更新于29 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com

Vue 进阶学习详细步骤(从 Router 到实战项目)

以下是针对 Vue Router、Pinia、组件库、Axios 的分阶段学习步骤,每个阶段都包含「核心概念→实操练习→常见问题」,最后通过「用户管理系统」实战串联所有知识点,确保学完能落地。

一、第一阶段:学习 Vue Router(单页应用路由核心)

1. 前置准备:明确学习目标

掌握「页面切换、路由传参、权限控制」,能实现类似 “首页→列表页→详情页” 的跳转逻辑,理解单页应用(SPA)的路由原理。

2. 步骤 1:安装并初始化 Vue Router

(1)安装依赖(在 Vue 项目根目录执行)

bash

# Vue 3 对应 Vue Router 4(必须安装 4.x 版本)
npm install vue-router@4

(2)创建路由目录结构

src 下新建 router 文件夹,创建 index.js(路由配置文件),目录结构如下:

plaintext

src/
├─ router/
│ └─ index.js # 路由配置
├─ views/       # 页面级组件(区别于 components 通用组件)
│ ├─ Home.vue # 首页
│ ├─ UserList.vue # 用户列表页
│ └─ UserDetail.vue # 用户详情页
└─ App.vue

(3)编写基础路由配置(src/router/index.js)

javascript

运行

// 1. 导入 Vue Router 核心函数和页面组件
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import UserList from '../views/UserList.vue'
import UserDetail from '../views/UserDetail.vue'

// 2. 定义路由规则:path(路径)→ component(对应页面)
const routes = [
{
   path: '/',        // 根路径
   name: 'Home',     // 路由名称(可选,用于编程式导航)
   component: Home   // 对应页面组件
},
{
   path: '/user-list',
   name: 'UserList',
   component: UserList
},
{
   path: '/user-detail/:id',  // 动态路由(:id 是参数,用于传用户 ID)
   name: 'UserDetail',
   component: UserDetail
}
]

// 3. 创建路由实例
const router = createRouter({
 history: createWebHistory(),  // 无 # 的路由模式(推荐)
 routes  // 传入路由规则
})

// 4. 导出路由实例(供 main.js 引入)
export default router

(4)在 main.js 中挂载路由

javascript

运行

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'  // 引入路由配置

// 挂载路由到 App
createApp(App).use(router).mount('#app')

(5)在 App.vue 中添加路由出口和导航

vue

<template>
 <div>
   <!-- 1. 路由导航(类似 a 标签,不会刷新页面) -->
   <nav>
     <router-link to="/">首页</router-link> |
     <router-link to="/user-list">用户列表</router-link>
   </nav>
   
   <!-- 2. 路由出口:匹配的页面组件会渲染到这里 -->
   <router-view />
 </div>
</template>

3. 步骤 2:核心功能实操(逐个突破)

(1)两种导航方式(声明式 + 编程式)

  • 声明式导航:用 <router-link>(已在上面实现,适合静态导航栏)。
  • 编程式导航:用 useRouter 函数(适合按钮点击等动态跳转),示例(在 UserList.vue 中):vue<template>
     <div>
       <h1>用户列表</h1>
       <!– 点击跳转到详情页,传用户 ID=123 –>
       <button @click=”goToDetail(123)”>查看用户 123 详情</button>
     </div>
    </template>

    <script setup>
    import { useRouter } from ‘vue-router’  // 导入路由钩子
    const router = useRouter()  // 获取路由实例

    // 编程式导航函数
    const goToDetail = (userId) => {
     // 方式 1:用 path + params(需配合动态路由)
     router.push({ path: `/user-detail/${userId}` })
     
     // 方式 2:用 name + params(需路由配置有 name)
     // router.push({ name: ‘UserDetail’, params: { id: userId } })
    }
    </script>

(2)路由传参与接收(动态路由参数)

在 UserDetail.vue 中接收 :id 参数:

vue

<template>
 <div>
   <h1>用户详情</h1>
   <p>当前用户 ID:{{ userId }}</p>
 </div>
</template>

<script setup>
import { useRoute } from 'vue-router'  // 注意:useRoute 是获取当前路由信息
const route = useRoute()

// 接收动态路由参数(route.params.参数名)
const userId = route.params.id
</script>

(3)嵌套路由(实现 “页面内子页面”)

比如在 UserList 页面内嵌套 “用户列表” 和 “用户统计” 子页面,步骤:

  1. 在 UserList.vue 中添加 <router-view>(子路由出口):vue<template>
     <div>
       <h1>用户列表</h1>
       <!– 子路由导航 –>
       <div>
         <router-link to=”/user-list/list”>列表视图</router-link> |
         <router-link to=”/user-list/stat”>统计视图</router-link>
       </div>
       <!– 子路由出口 –>
       <router-view />
     </div>
    </template>
  2. 在 router/index.js 中配置嵌套路由(用 children 字段):javascript运行const routes = [
     // …其他路由
    {
       path: ‘/user-list’,
       name: ‘UserList’,
       component: UserList,
       // 嵌套子路由
       children: [
        {
           path: ‘list’,  // 子路径(完整路径:/user-list/list)
           component: () => import(‘../views/UserList/List.vue’)  // 懒加载组件
        },
        {
           path: ‘stat’,  // 完整路径:/user-list/stat
           component: () => import(‘../views/UserList/Stat.vue’)
        },
        {
           path: ”,  // 默认子路由(访问 /user-list 时显示)
           redirect: ‘list’  // 重定向到 list 子路由
        }
      ]
    }
    ]

(4)路由守卫(权限控制)

比如 “未登录用户不能访问用户列表”,用全局前置守卫实现: 在 router/index.js 中添加:

javascript

运行

// 全局前置守卫:每次路由跳转前执行
router.beforeEach((to, from, next) => {
 // to:要跳转到的路由;from:从哪个路由来;next:是否允许跳转

 // 1. 定义需要登录的路由白名单
 const needLoginRoutes = ['UserList', 'UserDetail']
 
 // 2. 模拟是否登录(实际项目中从 Pinia/本地存储获取)
 const isLogin = localStorage.getItem('isLogin') === 'true'

 // 3. 判断:若要访问需要登录的路由且未登录,跳转到首页
 if (needLoginRoutes.includes(to.name) && !isLogin) {
   next({ path: '/' })  // 强制跳转首页
} else {
   next()  // 允许跳转
}
})

4. 步骤 3:巩固练习

  • 实现 “首页→商品列表→商品详情” 的路由跳转,包含:
    1. 商品列表页用编程式导航跳转到详情页,传递商品 ID;
    2. 详情页接收 ID 并显示;
    3. 给 “商品详情” 路由添加守卫,要求必须从 “商品列表” 跳转才能访问(用 from 判断)。

二、第二阶段:学习 Pinia(全局状态管理)

1. 前置准备:明确学习目标

解决 “多个组件共享数据” 的问题(比如用户登录状态、购物车数据),理解 “状态→动作→响应式” 的逻辑,替代 Vue 2 的 Vuex。

2. 步骤 1:安装并初始化 Pinia

(1)安装依赖

bash

npm install pinia

(2)创建 Pinia 实例并挂载(main.js)

javascript

运行

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import { createPinia } from 'pinia'  // 导入 Pinia

const app = createApp(App)
const pinia = createPinia()  // 创建 Pinia 实例

// 挂载 Pinia 和路由
app.use(pinia).use(router).mount('#app')

(3)创建第一个 Store(状态容器)

src 下新建 stores 文件夹,创建 userStore.js(用户相关状态):

javascript

运行

// 1. 导入 defineStore(定义 Store 的核心函数)
import { defineStore } from 'pinia'

// 2. 定义 Store:第一个参数是 Store 唯一 ID(必须唯一),第二个参数是配置
export const useUserStore = defineStore('user', {
 // ① state:存储全局状态(类似组件的 data)
 state: () => ({
   isLogin: false,  // 是否登录
   userInfo: {      // 用户信息
     name: '',
     id: '',
     role: ''       // 角色(普通用户/管理员)
  }
}),

 // ② actions:修改状态的函数(类似组件的 methods,支持异步)
 actions: {
   // 登录动作:接收用户信息参数,修改 state
   login(userData) {
     this.isLogin = true  // 直接修改 state(Pinia 无需 mutations)
     this.userInfo = userData
     // 存储到本地存储,避免刷新页面丢失
     localStorage.setItem('userInfo', JSON.stringify(userData))
     localStorage.setItem('isLogin', 'true')
  },

   // 退出登录动作
   logout() {
     this.isLogin = false
     this.userInfo = { name: '', id: '', role: '' }
     localStorage.removeItem('userInfo')
     localStorage.removeItem('isLogin')
  },

   // 异步动作:模拟从接口获取用户信息(配合 Axios 后续用)
   async fetchUserInfo() {
     // 实际项目中这里用 Axios 调用后端接口
     const mockData = await new Promise(resolve => {
       setTimeout(() => {
         resolve({ name: '张三', id: '123', role: 'admin' })
      }, 1000)
    })
     this.userInfo = mockData
     this.isLogin = true
  }
},

 // ③ getters:计算属性(类似组件的 computed,缓存结果)
 getters: {
   // 拼接用户名称和角色
   userDesc: (state) => {
     return `${state.userInfo.name}(${state.userInfo.role})`
  }
}
})

3. 步骤 2:核心功能实操

(1)在组件中使用 Store(登录案例)

创建 Login.vue 页面,实现登录并修改全局状态:

vue

<template>
 <div>
   <h1>登录页</h1>
   <input v-model="username" placeholder="请输入用户名" />
   <button @click="handleLogin">登录</button>
 </div>
</template>

<script setup>
import { ref } from 'vue'
import { useUserStore } from '../stores/userStore'  // 导入 Store
import { useRouter } from 'vue-router'

const username = ref('')
const userStore = useUserStore()  // 获取 Store 实例
const router = useRouter()

// 登录按钮点击事件
const handleLogin = () => {
 if (!username.value) return alert('请输入用户名')
 
 // 调用 Store 的 login 动作,传递用户数据
 userStore.login({
   name: username.value,
   id: '456',
   role: 'user'
})
 
 // 登录成功后跳转到用户列表
 router.push('/user-list')
}
</script>

(2)在其他组件中共享状态(用户列表页)

在 UserList.vue 中显示登录用户信息:

vue

<template>
 <div>
   <h1>用户列表</h1>
   <!-- 显示 Store 中的 getters 计算属性 -->
   <p>当前登录用户:{{ userStore.userDesc }}</p>
   <!-- 点击退出登录,调用 Store 的 logout 动作 -->
   <button @click="userStore.logout">退出登录</button>
 </div>
</template>

<script setup>
import { useUserStore } from '../stores/userStore'
const userStore = useUserStore()  // 直接获取 Store 实例,共享状态
</script>

(3)修改状态的两种方式

  1. 直接修改(简单场景):javascript运行const userStore = useUserStore()
    userStore.isLogin = true  // 直接修改 state 属性
  2. 通过 actions 修改(复杂场景,推荐,便于统一管理):javascript运行// 在 Store 中定义 actions,组件中调用
    userStore.login(userData)img

4. 步骤 3:巩固练习

  • 实现 “购物车 Store”,包含:
    1. state:cartList(购物车商品数组);
    2. actions:addCart(添加商品)、removeCart(删除商品)、clearCart(清空购物车);
    3. getters:cartTotal(计算购物车商品总数)、cartPrice(计算购物车总金额);
    4. 在 “商品详情页” 添加商品到购物车,在 “购物车页面” 显示并操作购物车。
文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇