3

How to pass an object as props in Vue 3 using the Vue Router? This can be achieved in Vue 2 following the accepted answer here and its corresponding JSFiddle. In Vue 3 this syntax stringifies pushed objects into "[object Object]" in contrast to Vue 2. I have tried with Vue 3 in the following fiddle.

const Home = { template: '<div>Home</div>',
               mounted: function() {
                this.$router.push({
                    name: "about",
                    params: {
                        user: "User Name",
                        objectParam: {a: "a"}
                    }
                  })
                }}
const About = { template: '<div>About</div>',
                                props: ['user', 'o', 'objectParam'],
                mounted: function(){
                    console.log( "Passed props:" )
                    console.log( this.$props )
                }}

const routes = [
  { path: '/', component: Home },
  { path: '/about', name:"about", component: About, 
                                  props: route => (
                                         console.log("Params defined here are passed as objects."),
                                         console.log("But route params object passed via push has already been stringified."),
                                         console.log(route.params),
                                         {o: {b: "b"},
                                          ...route.params
                                          })},
]


const router = VueRouter.createRouter({
  history: VueRouter.createWebHashHistory(),
  routes,
})

const app = Vue.createApp({})
app.use(router)
app.mount('#app')

Can objects be passed via Vue Router push() in Vue 3?

HHL
  • 87
  • 1
  • 9

3 Answers3

1

I can't find any official documentation from Vue Router to support that and to be honest I don't think it's a great idea to send dynamic objects as params, but if you really want to do so, one way to achieve it is to stringify your object and then parse it on the receiver side. So something like this:

this.$router.push({
    name: "about",
    params: {
        user: "User Name",
        objectParam: JSON.stringify({ a: "a" })
    }
})

And then in the other component:

JSON.parse(this.$route.params.objectParam)
hatef
  • 5,491
  • 30
  • 43
  • 46
  • Thanks and sorry, I should have been more explicit. I was specifically aiming to avoid using JSON.stringify into JSON.parse here as the object that I was trying to pass is rather large and JSON.stringify is slow in this case. – HHL Jan 09 '22 at 17:22
  • 1
    I see, well as I mentioned you should not pass large objects via params in my opinion. If it feels that way it might be a flaw in your application design. Consider refactoring your code and use store or events instead. – hatef Jan 09 '22 at 19:02
0

I'm going out on a limb and saying I don't think that's possible in Vue3.

You might take a look into a state manager like Vuex and see if it solves your problem. The state manager concept will allow you to keep a complex object across multiple views.

Mock Coder
  • 189
  • 5
0

One more thing to note, besides stringifying, if we take this object from Vuex now in Vue3 we will get a proxy. Which also creates a trouble.

To solve this we need to transform proxy into a normal object first, for example with lodash cloneDeep.

router.push({
  params: {
    objFromVuex: JSON.stringify(cloneDeep(objFromVuex))
  }
});

In order to read the value, just JSON.parse

const objFromVuex = JSON.parse(this.$route.params.objFromVuex);
Alonad
  • 1,986
  • 19
  • 17