Vue-router4 - 使用 <router-link :to> 传递对象不会传递动态数据

Posted

技术标签:

【中文标题】Vue-router4 - 使用 <router-link :to> 传递对象不会传递动态数据【英文标题】:Vue-router4 - Passing object with <router-link :to> won't pass dynamic data 【发布时间】:2021-07-14 16:16:03 【问题描述】:

我浏览了这个有点相关的vue-router@4.05 object params。在那个帖子中提到了这个https://github.com/vuejs/vue-router-next/issues/494,但我仍然很困惑。

我也在尝试使用 router link 组件的 :to 属性传递一些数据。我做了两支笔来展示这个问题:

Pen 1 传递了一个在路由定义中定义的对象 - 成功。

Pen 2 正在尝试传递一个动态对象,而不是实际对象,它得到一个带有 [Object object] 的字符串,如 github 问题中所述。

控制台输出:

[Vue 警告]:无效的道具:道具“存储库”的类型检查失败。预期的对象,得到具有>值“[对象对象]”的字符串。 在 在 在 在

所以,如果我明白这一点,最终你不能传递一个动态对象,因为它已被解析,但你可以传递一个静态对象?

我已经尝试过 props: true 和一切,我正在尝试 function mode 解决方案作为更复杂的示例

sn-ps:

    <router-link :to=" name: 'Home' ">Home</router-link>
    <router-view />

    <router-link
      :to="
        name: 'Repository',
        params:  repository:  one: '1', two: '2'  ,
      ">click me</router-link>

v1

    const routes: Array<RouteRecordRaw> = [
    
      path: "/",
      name: "Home",
      component: Home
    ,
    
      path: "/repo/",
      name: "Repository",
      component: () => import("../components/Repository.vue"),
      props: (route) => 
        console.log("entered route");
        console.log(route);
        return  ...route.params, repository:  one: "1", two: "2"  ;
      
    ];

v2

    const routes: Array<RouteRecordRaw> = [
    
      path: "/",
      name: "Home",
      component: Home
    ,
    
      path: "/repo/",
      name: "Repository",
      component: () => import("../components/Repository.vue"),
      props: (route) => 
        console.log("entered route");
        console.log(route);
        return  ...route.params ;
      
    ];

【问题讨论】:

【参考方案1】:

您的代码中发生了什么:

正如您在控制台中的警告消息中看到的那样,您实际上是从道具中获得 String 而不是 Object

[Vue 警告]:无效的道具:道具“存储库”的类型检查失败。 预期对象,得到字符串

很多人建议使用 Vuex 并将全局状态设置为解决方案,我认为这不是您想要的。

解决方案

为避免将[Object, Object]作为传递的数据,您可以做的是在原始页面中将您的对象字符串化,然后在您的目标页面上再次将传递的字符串解析为对象。

原始页面/路由器组件

 <router-link
      :to="
        name: 'Your_Route_Name',
        params:  repository: JSON.stringify( one: '1', two: '2' ) ,
      ">click me</router-link>

在您的目标路由器组件中

<template>
    <div>
         JSON.parse(repository) 
    </div>
</template>

<script>
export default 
    props: ["repository"],
    setup(props) 
        //Log the parsed object in console. Example shown with Vue3 Composition API but you get the idea.
        console.log(JSON.parse(props.customer));
    

</script>

这样,您将能够按意图传递 Object。

【讨论】:

【参考方案2】:

Vue-router 从未支持传递任意数据(未在路由定义中定义为 params),并且从未按预期工作。检查我的answer on the question you linked

您的示例 v1 之所以有效,是因为在路由的 props 函数中定义的 repository 的值会覆盖从 router-linkparams 传递的 repository 值(您可以使用 repository: "[object Object]"在控制台中查看)

所以,如果我明白这一点,最终你不能传递一个动态对象,因为它已被解析,但你可以传递一个静态对象?

没有。

    您不能使用 $router.pushrouter-link 传递任何对象(即使它在 Vue-router 3 中“有点工作” - 再次,请参阅我的链接答案)

    您可以在路由定义中将props 定义为对象或函数返回对象,它的属性将通过传递给组件的道具而无需任何编码或任何东西。但这与使用$router.pushrouter-link 有很大不同,因为数据不是来自源路由,而是来自路由器本身...

【讨论】:

1.老实说,我确实阅读了您的答案以及对它确实适用于 vue2 的所有回复,这增加了我的困惑。 2.我猜你的意思是道具:真正的语法?最后,也许有点离题,我猜想实现这样的场景(从带有路由器链接的组件传递数据 - 如果这有意义的话 - 将需要 vuex 或某种形式的状态管理? 1.我知道,互联网上有很多关于这个话题的混淆,因为它乍一看“有点工作”。但是,一旦您在可以使用 Back/Forward 的真实应用程序中使用它,所有示例都会中断。 2. 不,我的意思是props as object 或props as function(正如您在示例中使用的那样) 全局状态管理 + 通过路由参数仅传递某种 id 只是一种解决方案。不仅是一个,而且绝对不是最好的。另一种方法是使用query + 某种复杂对象的序列化/反序列化(for example)。

以上是关于Vue-router4 - 使用 <router-link :to> 传递对象不会传递动态数据的主要内容,如果未能解决你的问题,请参考以下文章

vue-router

Vue + vue-router

vue-router 利用url传递参数

vue-router $route

vue-router-5-命名路由

Vue-Router的使用