NikOs
NikOs

Reputation: 52

Vue-router4 - Passing object with <router-link :to> won't pass dynamic data

I went through this [email protected] object params which is somewhat related. There is a mention of this https://github.com/vuejs/vue-router-next/issues/494 in that thread, but I am still confused.

I am also trying to pass some data using the :to attribute of the router link component. I have made two pens to showcase the issue:

Pen 1 passes an object that is defined within the routes definition - successfully.

Pen 2 is trying to pass a dynamic object and instead of the actual object it gets a string with [Object object] as described in the github issue.

console output:

[Vue warn]: Invalid prop: type check failed for prop "repository". Expected Object, got String with >value "[object Object]". at <Repository repository="[object Object]" onVnodeUnmounted=fn ref=Ref > at at at

So, if I get this straight, ultimately you cant pass a dynamic object cos it's parsed, but you can pass a static object?

I have tried with props: true and everything, I am trying the function mode solution as a more complex example

snippets:

    <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 };
      }
    }];

Upvotes: 1

Views: 5051

Answers (2)

Andre W.
Andre W.

Reputation: 1023

What's happening in your code:

As you can see in the warning message in the console, you are actually getting String from the prop instead of Object:

[Vue warn]: Invalid prop: type check failed for prop "repository". Expected Object, got String

Many people suggest using Vuex and set global states as the solution, which I believe is not what you are looking for.

Solution

To avoid getting [Object, Object] as the passed data, what you can do is to stringify your object in the original page, and then parse the passed string into an object again on your targeted page.

Original page/router component

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

In your targeted router component

<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>

This way, you will be able to pass Object as intented.

Upvotes: 5

Michal Lev&#253;
Michal Lev&#253;

Reputation: 37803

Passing arbitrary data (not defined in route definition as params) was never supported in Vue-router and never worked as expected. Check my answer on the question you linked

Your example v1 works only because the value of repository defined in props function of the route overwrites the repository value passed from router-link through params (which is repository: "[object Object]" as you can see in the console)

So, if I get this straight, ultimately you cant pass a dynamic object cos it's parsed, but you can pass a static object?

No.

  1. You can't pass any object using $router.push or router-link (even it "sort of worked" in Vue-router 3 - again, see my linked answer)

  2. You can define props on the route definition as an object or as a function returning object and it's properties will by passed to your component's props without any encoding or anything. But this is very different from using $router.push or router-link as the data does not come from source route but from router itself...

Upvotes: 2

Related Questions