描述业务场景:
vue3项目中有一个业务场景
Task1View.vue
Task2View.vue
路由
{
path: "/task1/:userId?",
name: "task1",
component: Task1View,
},
{
path: "/task2/:userId?",
name: "task2",
component: Task2View,
},
无论是task1还是task2访问的时候都要获取到userId,并且根据userId做一些查询,查询结果返回username显示在task1和task2中.请问该怎么写代码?
处理过程:
使用路由守卫:
// stores/userStore.js
import { defineStore } from 'pinia'
import { ref } from 'vue'
export const useUserStore = defineStore('user', () => {
const username = ref('')
const loading = ref(false)
const fetchUserInfo = async (userId) => {
if (!userId) return
loading.value = true
try {
const response = await fetch(`/api/users/${userId}`)
const data = await response.json()
username.value = data.username
} catch (error) {
console.error('Failed to fetch user info:', error)
} finally {
loading.value = false
}
}
return {
username,
loading,
fetchUserInfo
}
})
路由守卫中处理:
// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import { useUserStore } from '@/stores/userStore'
const router = createRouter({
history: createWebHistory(),
routes: [
{
path: "/task1/:userId?",
name: "task1",
component: () => import('@/views/Task1View.vue'),
},
{
path: "/task2/:userId?",
name: "task2",
component: () => import('@/views/Task2View.vue'),
},
]
})
// 全局前置守卫
router.beforeEach(async (to, from) => {
// 检查是否是需要用户信息的页面
if (to.name === 'task1' || to.name === 'task2') {
const userId = to.params.userId
if (userId) {
const userStore = useUserStore()
await userStore.fetchUserInfo(userId)
}
}
})
export default router
组件中的使用:
<!-- Task1View.vue -->
<template>
<div>
<div v-if="userStore.loading">Loading...</div>
<div v-else>
<h1>Task 1 - User: {{ userStore.username || 'No user selected' }}</h1>
<!-- 其他内容 -->
</div>
</div>
</template>
<script setup>
import { useUserStore } from '@/stores/userStore'
const userStore = useUserStore()
</script>
什么是 Pinia?
1. 官方推荐的状态管理库
-
Vue 官方团队开发和维护
-
类型安全,完美支持 TypeScript
-
API 设计简单直观
安装pinia:
npm install pinia
# 或
yarn add pinia
vue中使用pinia:
// main.js
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
const app = createApp(App)
const pinia = createPinia()
app.use(pinia)
app.mount('#app')