Vue3 路由跳转传值方法

了解 Vue 3 中路由跳转时传值的方法是开发中的常见需求。由于 Vue 3 引入了 Composition API,路由的使用方式与 Vue 2 有所不同。下面我将为你梳理几种主要的路由传值方式。

下面是一个汇总表格,帮助你快速了解各种传值方式的特点:

传值方式 特点 适用场景 页面刷新后数据是否保留
动态路由参数 (Params) 参数是 URL 的一部分 (如 /user/123) 传递必要标识符,如用户ID、文章ID等
查询参数 (Query) 参数以键值对形式附在 URL 后 (如 ?name=John&age=30) 传递可选或过滤参数,如搜索关键字、分页信息、筛选条件
路由状态 (State) 参数不会暴露在 URL 中,通过路由对象的 state 属性传递 传递敏感或临时数据,如表单数据、大量数据
Props 解耦 将路由参数作为组件的 Props 传入,而非在组件内直接依赖 $route 提高组件的可复用性和可测试性,减少与路由的耦合 同 Params/Query

🧭 路由传值操作步骤
在 Vue 3 中,路由跳转传参通常遵循以下步骤:

  1. 引入 API:在需要跳转的组件中,引入 useRouter
  2. 执行跳转:调用 router.push 等方法进行跳转,并传入参数。
  3. 接收参数:在目标组件中,引入 useRoute,并通过 route 对象获取传递过来的参数。

🔧 具体使用方式

1. 动态路由参数 (Params)

动态路由参数是 URL 的一部分,适合传递像用户 ID、文章编号这类标识符。

  • 定义路由:在路由配置中使用冒号 : 指定动态参数。
    // router/index.js
    import { createRouter, createWebHistory } from 'vue-router';
    const routes = [
      // ... 其他路由
      {
        path: '/user/:id', // 定义动态路由参数 id
        name: 'UserDetail',
        component: UserDetail
      }
    ];
    const router = createRouter({
      history: createWebHistory(),
      routes
    });
    export default router;
    
  • 传递参数:使用 router.push 并指定 params
    <script setup>
    import { useRouter } from 'vue-router';
    const router = useRouter();
    const gotoUserDetail = (userId) => {
      router.push({
        name: 'UserDetail', // 使用命名的路由,传递 params 时必须用 name
        params: { id: userId } // 传递参数,键需与路由定义中的动态段匹配
      });
      // 或者 router.push(`/user/${userId}`); // 直接写 path
    };
    </script>
    
  • 接收参数:在目标组件中使用 useRoute 获取 params
    <script setup>
    import { useRoute } from 'vue-router';
    const route = useRoute();
    // 获取动态路由参数
    const userId = route.params.id; // 例如,URL 是 /user/123, 则 userId 为 '123'
    </script>
    
    注意:如果提供了 pathparams 会被忽略,此时需要提供路由的 name 或手写完整的带有参数的 path

2. 查询参数 (Query)

查询参数以键值对的形式附加在 URL 末尾(?key=value),适合传递可选参数或过滤条件。

  • 传递参数:使用 router.push 并指定 query
    <script setup>
    import { useRouter } from 'vue-router';
    const router = useRouter();
    const gotoUserList = (pageNum, filters) => {
      router.push({
        path: '/users',
        query: { 
          page: pageNum, 
          sort: filters.sortBy 
        } // 传递查询参数
      });
      // 或使用 name: router.push({ name: 'UserList', query: { ... } });
    };
    </script>
    
    跳转后 URL 会变为类似 /users?page=2&sort=name 的形式。
  • 接收参数:在目标组件中使用 useRoute 获取 query
    <script setup>
    import { useRoute } from 'vue-router';
    const route = useRoute();
    // 获取查询参数
    const currentPage = route.query.page;
    const sortType = route.query.sort;
    </script>
    

3. 路由状态 (State)

Vue Router 允许在跳转时通过 state 传递一些不会显示在 URL 中的临时数据。

  • 传递参数:使用 router.push 并指定 state
    <script setup>
    import { useRouter } from 'vue-router';
    const router = useRouter();
    const gotoResult = (formData) => {
      router.push({
        name: 'ResultPage',
        state: { 
          submittedData: formData // 通过 state 传递数据
        }
      });
    };
    </script>
    
  • 接收参数:在目标组件中通过 router.currentRoute.value.state 获取。
    <script setup>
    import { useRouter } from 'vue-router';
    const router = useRouter();
    // 获取通过 state 传递的参数
    const submittedData = router.currentRoute.value.state?.submittedData;
    </script>
    
    注意:通过 state 传递的数据不会在页面刷新后保留,且不会暴露在 URL 中,适合敏感或临时数据。

4. 使用 Props 解耦

可以将路由参数作为 Props 传递给组件,从而减少组件与 $route 的直接耦合,提高组件的可复用性和可测试性。

  • 配置路由:在路由配置中设置 props: true(对于动态路由参数)或使用函数形式(更灵活)。
    // router/index.js
    {
      path: '/user/:id',
      name: 'UserDetail',
      component: UserDetail,
      props: true // 开启 props 传参,route.params 将设置为组件的 props
      // 或者使用函数形式更灵活地返回 props 对象
      // props: (route) => ({ id: route.params.id, query: route.query.search })
    }
    
  • 接收参数:在目标组件中像接收普通 props 一样使用。
    <script setup>
    defineProps({
      id: {
        type: String,
        required: true
      }
    });
    </script>
    

⚠️ 注意事项与技巧

  1. Params 与 Query 的区别

    • params 是 URL 的一部分,通常用于标识唯一资源。如果路由定义了 params 但跳转时未提供,可能会导致导航失败。
    • query 是查询字符串,可选参数。更适合过滤、分页等场景。
  2. 响应参数变化:当同一个组件仅因参数(如从 /user/1/user/2)不同而重新渲染时,组件的 mounted 等生命周期钩子不会再次执行。为了响应参数变化,你可以:

    • 使用 watch 监听 route 对象上的 paramsquery
    <script setup>
    import { watch } from 'vue';
    import { useRoute } from 'vue-router';
    const route = useRoute();
    watch(() => route.params.id, (newId) => {
      // 当 id 变化时,执行数据获取等操作
      fetchUserData(newId);
    });
    </script>
    
    • 或者使用 onBeforeRouteUpdate 导航守卫(需引入 vue-router)。
  3. 何时使用其他状态管理:对于复杂的应用状态共享(如用户登录信息、全局主题),或需要跨多个非父子关系组件共享的数据,使用 Pinia (Vue 3 推荐的状态管理库) 或 Vuex 通常是比路由传参更好的选择。

💡 如何选择传值方式

选择哪种方式取决于你的具体需求:

  • 需要在URL中体现参数,并且刷新页面后参数不丢失

    • :使用 Params (用于必要标识符) 或 Query (用于过滤、分页等选项)。
    • :考虑使用 State(用于敏感数据、临时数据或大数据量)。
  • 希望组件能更方便地复用和测试,减少对路由的依赖?

    • :在路由配置中开启 Props 传参。
posted @ 2025-10-10 10:00  dirgo  阅读(206)  评论(0)    收藏  举报