微信公众号
扫描关注微信公众号
博客大厅

Pinia 如何与 Vue Router 集成?

原创 来源:博客站 阅读 0 03月22日 07:32 听全文

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 的集成可以通过以下方式实现:

  1. 在 Store 中访问路由信息:使用 useRouteuseRouter
  2. 在路由守卫中使用 Store:实现权限控制或状态检查。
  3. 在 Store 中监听路由变化:通过 watch 监听路由变化。
  4. 在 Store 中管理导航历史:保存和恢复导航历史。
  5. 在 Store 中保存路由状态:例如保存滚动位置。

通过这些方法,Pinia 和 Vue Router 可以紧密协作,为应用提供强大的状态管理和路由控制功能。

学在每日,进无止境!更多精彩内容请关注微信公众号。
原文出处: 内容由AI生成仅供参考,请勿使用于商业用途。如若转载请注明原文及出处。
出处地址:http://www.07sucai.com/tech/834.html
版权声明:本文来源地址若非本站均为转载,若侵害到您的权利,请及时联系我们,我们会在第一时间进行处理。
轻松 一刻
>