74 votes

Passage de props aux composants Vue.js instanciés par Vue-router

Supposons que j'ai un composant Vue.js comme celui-ci :

var Bar = Vue.extend({
    props: ['my-props'],
    template: '<p>This is bar!</p>'
});

Et je veux l'utiliser lorsqu'une route dans vue-router est mise en correspondance comme ceci :

router.map({
    '/bar': {
        component: Bar
    }
});

Normalement, pour passer "mesProps" au composant, je devrais faire quelque chose comme ceci :

Vue.component('my-bar', Bar);

et dans le html :

<my-bar my-props="hello!"></my-bar>

Dans ce cas, le routeur dessine automatiquement le composant dans l'élément router-view lorsque la route est mise en correspondance.

Ma question est la suivante : dans ce cas, comment puis-je passer les props au composant ?

95voto

lukpep Points 781
<router-view :some-value-to-pass="localValue"></router-view>

et dans vos composants, ajoutez simplement prop :

props: {
      someValueToPass: String
    },

vue-router correspondra à la prop dans le composant

2 votes

Alternativement, props: ["prop1", "prop2", "prop3"] Vous trouverez plus d'informations ici vuejs.org/guide/composants.html#Props

2 votes

@lukpep j'ai rencontré quelque chose de similaire, quand je lie mon prop sur <router-view> J'ai obtenu l'erreur suivante Attribute ":my_prop" is ignored on component <router-view> because the component is a fragment instance . Une idée de ce qui ne va pas ?

5 votes

C'est peut-être une mauvaise idée. Que se passe-t-il lorsque l'utilisateur arrive directement via l'URL ?

47voto

ctf0 Points 3640

Malheureusement, aucune des solutions précédentes ne répond réellement à la question. quora

en fait, la partie qui docs n'explique pas bien est

Lorsque props a la valeur true, le route.params sera défini comme le composant props.

donc ce dont vous avez besoin lorsque vous envoyez l'accessoire par la route, c'est de l'assigner à l'option params ex clé

this.$router.push({
    name: 'Home',
    params: {
        theme: 'dark'
    }
})

L'exemple complet serait donc

// component
const User = {
  props: ['test'],
  template: '<div>User {{ test }}</div>'
}

// router
new VueRouter({
  routes: [
    { 
      path: '/user',
      component: User,
      name: 'user',
      props: true 
    }
  ]
})

// usage
this.$router.push({
    name: 'user',
    params: {
        test: 'hello there' // or anything you want
    }
})

2 votes

Cela signifie-t-il que cela ne peut être réalisé qu'avec des itinéraires nommés ?

1 votes

Pas de router.vuejs.org/guide/essentiels/ mais il est préférable d'utiliser des routes nommées "plus faciles à entretenir".

14voto

Jegadesh B S Points 407

Dans le routeur,

const router = new VueRouter({
  routes: [
    { path: 'YOUR__PATH', component: Bar, props: { authorName: 'Robert' } }
  ]
})

Et à l'intérieur de la <Bar /> composant,

var Bar = Vue.extend({
    props: ['authorName'],
    template: '<p>Hey, {{ authorName }}</p>'
});

1voto

aboutqx Points 231
 const User = {
      props: ['id'],
      template: '<div>User {{ id }}</div>'
    }
    const router = new VueRouter({
      routes: [
        { path: '/user/:id', component: User, props: true }

        // for routes with named views, you have to define the props option for each named view:
        {
          path: '/user/:id', 
          components: { default: User, sidebar: Sidebar },
          props: { default: true, sidebar: false }
        }
      ]
    })

Mode objet

const router = new VueRouter({
  routes: [
    { path: '/promotion/from-newsletter', component: Promotion, props: { newsletterPopup: false } }
  ]
})

C'est la réponse officielle. lien

8 votes

Dans cette situation, où passerait-on la chaîne "hello", comme cela a été demandé ?

1 votes

Lire plus loin dans les documents officiels : "Lorsque props est défini à true, route.params sera défini comme props du composant." L'auteur demandait comment définir une valeur personnalisée "hello".

30 votes

J'adore quand les gens se contentent de copier et coller la documentation officielle qui ne répond pas à la question. Nous avons tous vu la documentation officielle et elle ne répond pas à la question de l'OP, donc la coller à nouveau sans explication ou clarification et s'en aller n'ajoute pas de valeur au post.

0voto

mike Points 3565

Pour répondre directement à la question, à l'heure où j'écris ces lignes, il n'y a pas de moyen direct de faire ce que vous voulez (en dehors de ceux déjà montrés par les réponses précédentes). Mais même si c'était le cas, je ne pense pas qu'il soit recommandé de le faire.

Une url est la représentation d'une ressource, et c'est cette ressource (parfois avec son url) qui entraînera un changement d'état. Une url peut contenir des données d'état, mais elle est limitée au protocole, à l'hôte, au chemin et à la chaîne de requête. Tout ce qui est plus élaboré doit être transporté dans le cadre d'une ressource récupérée ou générée en réponse à la requête/navigation.

Transmettre des données au composant via le routeur s'apparente à un accord secret. Vous donnez un état sans passer par les canaux appropriés, ce qui signifie que le composant acquiert un état non pas en réponse directe à la navigation, mais en raison d'un mécanisme obscur. Normalement, l'état devrait changer en tant que réaction au changement d'url, pas par une logique alternative. Cela rend votre application plus prévisible.

Les situations dans lesquelles il peut être tentant de faire passer les données par le routeur sont généralement celles où les données sont déjà présentes et où il semble redondant ou inutile de les demander à nouveau. Mais que se passe-t-il si vous ouvrez simplement le navigateur sur cette url, d'où doivent provenir les données ? Si le raisonnement est que l'on ne s'attend pas à ce que les données soient simplement déposées à cet endroit, alors peut-être n'avez-vous pas besoin d'une route qui y mène, peut-être avez-vous simplement besoin de quelque chose avec un gestionnaire d'événement de clic qui chargera un composant et transmettra les données de la manière que vous voulez.

Si, en revanche, vous pensez avoir besoin de la route (donc d'un routeur) pour accéder à la ressource, ce type de scénario convient parfaitement à un gestionnaire d'état (c'est-à-dire quelque chose comme Vuex).

Ainsi, au lieu de transmettre les données au composant via le routeur, il suffit de lui fournir le minimum nécessaire pour qu'il puisse interroger le gestionnaire d'état pour obtenir les données supplémentaires, plus complètes (c'est-à-dire utiliser simplement vue-router et vuex comme ils sont censés être utilisés).

Si vous voulez éviter la redondance lors de la récupération des données, utilisez un mécanisme de mise en cache dans votre gestionnaire d'état.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X