A
A
Anton2021-01-20 23:36:13
Vue.js
Anton, 2021-01-20 23:36:13

How to pass props to a component in Vue 3 via routing?

There was such a problem when building a simple application on pure Vue 3: There is a main component in which the posts array is located and there is a Home component for routing, which in turn contains the post component.

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <!-- google fonts -->
    <link rel="preconnect" href="https://fonts.gstatic.com" />
    <link
      href="https://fonts.googleapis.com/css2?family=Ubuntu:ital,[email protected],700;1,400&display=swap"
      rel="stylesheet"
    />
    <!-- styles -->
    <link rel="stylesheet" href="style.css" />
    <title>Posts</title>
  </head>
 <body>
   <div id="app">
      <div class="container">
        <router-view></router-view>
     </div>
   </div>
    <!-- Vue -->
    <script src="https://unpkg.com/[email protected]/dist/vue.global.js"></script>
    <script src="main.js"></script>

    <!-- Vue router -->
    <script src="https://unpkg.com/[email protected]/dist/vue-router.global.js"></script> 
     <script>
      const mountedApp = app.mount('#app')
    </script>
 </body>
</html>


main.js
const app = Vue.createApp({
  data() {
    return {
      posts: [],
    }
  }
});


router.js
const home = {
  props: ['posts'],
    template:
  /*html*/
`<h1 class="title">Latest posts</h1>
  <div class="posts">
    <post :posts="posts"></post>
  </div>`
}

const routes = [
  {path: '/', component: home},
]

const router = VueRouter.createRouter({
history:VueRouter.createWebHistory(),
routes
})
app.use(router)


How do I pass the posts array from main.js to the Home route (which is in route.js) via a prop?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
0
0xD34F, 2021-01-21
@SweeTooth

First, a couple of words about how to do it right:
Routing for data transfer in this situation should not be used. You connect vuex, put the array in the storage, the home component does not take any parameters, it just gets the necessary data from the storage and passes it to the posts component: As you can see, everything is elementary . Transferring "through routing" will turn into shitty coding:
<posts :posts="$store.state.posts" />

  • You can make the route named and pass it through params:
    <router-link :to="{ name: 'home', params: { posts } }">home</router-link>

    this.$router.push({
      name: 'home',
      params: {
        posts: this.posts,
      },
    });

    The first drawback of this method is immediately obvious: in how many places there is a transition to the home route, so many times you have to explicitly pass the posts array there, specifying it in the params of each router-linkor call $router.push. At the same time, if the transition is not carried out from the root component, then in order to reach posts, you will also have to $rootuse. In the case when the user decides to make the transition through the address bar of the browser, then nothing will be transmitted.
    Another drawback will become apparent after the transition - it turns out that the elements of the posts have turned into strings. The router casts the params property values ​​to strings (or, if the property is an array, its elements will be cast to strings). So for the correct transmission, you still have to convert the data into json, and parse this json in the home component - shit code, as promised .
  • You can attach data to router-view, then they will be passed as parameters to the current route component: . Here, too, not everything will go smoothly - so the parameters will be passed to the components of all routes, and where the parameters passed are not described, they will be considered attributes and attached to the root element (if there is one; when there are several, you must explicitly indicate where to add ). To pass what you need only where you need it, you can arrange the parameters passed to as a calculated property, the value of which will depend on the current route :<router-view :posts="post" />
    computed: {
      routeParams() {
        return что-то, в зависимости от this.$route;
      },
    },

    <router-view v-bind="routeParams" />

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question