
Pinia 与 Vue Router 的集成非常简单。Pinia 是一个状态管理库,而 Vue Router 是路由管理库,它们可以独立使用,也可以通过一些技巧实现协同工作。以下是 Pinia 与 Vue Router 集成的几种常见方式:
1. 在 Store 中访问路由信息
你可以在 Store 中访问 Vue Router 的当前路由信息,例如路径、参数或查询字符串。
示例:在 Store 中访问路由
// stores/router.ts
import { defineStore } from 'pinia';
import { useRouter, useRoute } from 'vue-router';
export const useRouterStore = defineStore('router', {
state: () => ({
currentRoute: null as any, // 保存当前路由信息
}),
actions: {
updateRoute() {
const route = useRoute();
this.currentRoute = route;
},
navigateTo(path: string) {
const router = useRouter();
router.push(path);
},
},
});
在组件中使用
<template>
<div>
<p>Current Path: {{ routerStore.currentRoute.path }}</p>
<button @click="goToHome">Go to Home</button>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { useRouterStore } from '@/stores/router';
export default defineComponent({
setup() {
const routerStore = useRouterStore();
routerStore.updateRoute(); // 更新当前路由信息
function goToHome() {
routerStore.navigateTo('/'); // 导航到首页
}
return {
routerStore,
goToHome,
};
},
});
</script>
2. 在路由守卫中使用 Store
你可以在 Vue Router 的路由守卫中访问 Pinia Store,以实现权限控制或状态检查。
示例:在路由守卫中使用 Store
// router/index.ts
import { createRouter, createWebHistory } from 'vue-router';
import { useAuthStore } from '@/stores/auth';
const router = createRouter({
history: createWebHistory(),
routes: [
{ path: '/', component: () => import('@/views/Home.vue') },
{ path: '/admin', component: () => import('@/views/Admin.vue'), meta: { requiresAuth: true } },
],
});
router.beforeEach((to, from, next) => {
const authStore = useAuthStore();
if (to.meta.requiresAuth && !authStore.isAuthenticated) {
next('/login'); // 重定向到登录页
} else {
next(); // 继续导航
}
});
export default router;
3. 在 Store 中监听路由变化
你可以通过 Vue Router 的 useRoute
钩子监听路由变化,并在 Store 中更新状态。
示例:监听路由变化
// stores/router.ts
import { defineStore } from 'pinia';
import { useRoute } from 'vue-router';
import { watch } from 'vue';
export const useRouterStore = defineStore('router', {
state: () => ({
currentRoute: null as any,
}),
actions: {
setupRouteListener() {
const route = useRoute();
watch(
() => route.path,
(newPath) => {
this.currentRoute = route;
console.log('Route changed:', newPath);
},
{ immediate: true }
);
},
},
});
在组件中启用监听
<template>
<div>
<p>Current Path: {{ routerStore.currentRoute.path }}</p>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { useRouterStore } from '@/stores/router';
export default defineComponent({
setup() {
const routerStore = useRouterStore();
routerStore.setupRouteListener(); // 启用路由监听
return {
routerStore,
};
},
});
</script>
4. 在 Store 中管理导航历史
你可以在 Store 中保存导航历史,以便实现“返回上一页”或“前进到下一页”的功能。
示例:管理导航历史
// stores/router.ts
import { defineStore } from 'pinia';
import { useRouter } from 'vue-router';
export const useRouterStore = defineStore('router', {
state: () => ({
history: [] as string[], // 保存导航历史
}),
actions: {
navigateTo(path: string) {
const router = useRouter();
router.push(path);
this.history.push(path); // 添加到历史记录
},
goBack() {
const router = useRouter();
if (this.history.length > 1) {
this.history.pop(); // 移除当前路径
const previousPath = this.history[this.history.length - 1];
router.push(previousPath); // 导航到上一页
}
},
},
});
在组件中使用
<template>
<div>
<button @click="goToAbout">Go to About</button>
<button @click="goBack">Go Back</button>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { useRouterStore } from '@/stores/router';
export default defineComponent({
setup() {
const routerStore = useRouterStore();
function goToAbout() {
routerStore.navigateTo('/about'); // 导航到 About 页
}
function goBack() {
routerStore.goBack(); // 返回上一页
}
return {
goToAbout,
goBack,
};
},
});
</script>
5. 在 Store 中保存路由状态
你可以将路由相关的状态(如当前页面的滚动位置)保存到 Store 中,以便在导航时恢复。
示例:保存滚动位置
// stores/router.ts
import { defineStore } from 'pinia';
import { useRoute } from 'vue-router';
import { watch } from 'vue';
export const useRouterStore = defineStore('router', {
state: () => ({
scrollPositions: {} as Record<string, number>, // 保存每个路径的滚动位置
}),
actions: {
saveScrollPosition(path: string, position: number) {
this.scrollPositions[path] = position;
},
restoreScrollPosition(path: string) {
return this.scrollPositions[path] || 0;
},
},
});
在组件中使用
<template>
<div ref="container" class="scrollable-container">
<!-- 内容 -->
</div>
</template>
<script lang="ts">
import { defineComponent, ref, onMounted } from 'vue';
import { useRoute } from 'vue-router';
import { useRouterStore } from '@/stores/router';
export default defineComponent({
setup() {
const route = useRoute();
const routerStore = useRouterStore();
const container = ref<HTMLElement | null>(null);
onMounted(() => {
const savedPosition = routerStore.restoreScrollPosition(route.path);
if (container.value) {
container.value.scrollTop = savedPosition;
}
container.value?.addEventListener('scroll', () => {
if (container.value) {
routerStore.saveScrollPosition(route.path, container.value.scrollTop);
}
});
});
return {
container,
};
},
});
</script>
总结
Pinia 与 Vue Router 的集成可以通过以下方式实现:
- 在 Store 中访问路由信息:使用
useRoute
和useRouter
。 - 在路由守卫中使用 Store:实现权限控制或状态检查。
- 在 Store 中监听路由变化:通过
watch
监听路由变化。 - 在 Store 中管理导航历史:保存和恢复导航历史。
- 在 Store 中保存路由状态:例如保存滚动位置。
通过这些方法,Pinia 和 Vue Router 可以紧密协作,为应用提供强大的状态管理和路由控制功能。
学在每日,进无止境!更多精彩内容请关注微信公众号。

原文出处:
内容由AI生成仅供参考,请勿使用于商业用途。如若转载请注明原文及出处。
出处地址:http://www.07sucai.com/tech/834.html
版权声明:本文来源地址若非本站均为转载,若侵害到您的权利,请及时联系我们,我们会在第一时间进行处理。