2 votes

Gestion d'URL avec Django, GraphQL, Apollo et VueJS

Comme dit dans le titre, j'utilise Django, GraphQL, Apollo et VueJS dans mon projet. Je le développe en tant qu'application à page unique (SPA).

Tout fonctionne bien, jusqu'à ce que je presse le bouton F5 et actualise la page. En effet, cela affiche une page inconnue. Le problème est que c'est VueRouter qui gère l'application à page unique et cela fonctionne bien. Mais lorsque je presse F5, c'est Django qui essaie de servir une page pour l'URL actuelle et comme il ne la connaît pas, il ne peut pas servir la page appropriée.

Je sais que je peux définir le mode 'history' de VueRouter, ce que j'ai fait, et ajouter une URL à Django qui sert index.html quelle que soit l'URL.

Mon problème est le suivant : Quand je suis sur une vue de formulaire particulière (par exemple : une vue de formulaire utilisateur), mon URL est la suivante :

http://localhost:8000/user

Comme j'utilise GraphQL pour mon API, les données récupérées ne sont pas basées sur l'URL. En fait, c'est mon composant VueJS qui dit : Hé Apollo, lance ce GraphQL pour récupérer l'utilisateur que je veux.

Donc lorsque je rafraîchis, oui, cela sert la vue du formulaire utilisateur..mais vide.

La question est : Comment puis-je résoudre cela ?

Pour des fins de clarification, voici quelques extraits de code :

Mes URLs Django :

# (... autres imports ici ...)
from .schema import schema

urlpatterns = [
    path('admin/', admin.site.urls),
    path('graphql', csrf_exempt(GraphQLView.as_view(graphiql=True, schema=schema))),  # 'schema' est le schéma principal GraphQL
    path('', TemplateView.as_view(template_name='index.html')),
    re_path(r'^.*$', TemplateView.as_view(template_name='index.html'))  # J'ai vu ça plusieurs fois pour servir la page quelle que soit l'URL lors du rafraîchissement de la page
]

Mon Vue Router :

export default new Router({
  mode: 'history',
  routes: [
    { path: '/', name: 'MainApp' },
    // ...
    { path: '/users', name: 'UserList', component: UserList },
    { path: '/user/create', name: 'UserFormCreate', component: UserForm, props: true },
    { path: '/user', name: 'UserFormView', component: UserForm, props: true },
    { path: '/user/edit', name: 'UserFormEdit', component: UserForm, props: true },
    // Même schéma pour d'autres modèles comme 'Groupe' ...
  ]

Mon Exemple de Composant VueJS :

import {
  // ...
  USER_QUERY,
  // ...
} from '../../graphql/base/user.js'

export default {
  name: 'UserForm',
  props: {
    userId: Number,
    editing: {
      type: Boolean,
      default: false
    }
  },
  apollo: {
    user: {
      query: USER_QUERY,
      variables () { return { id: this.userId } },
      skip () { return this.userId === undefined },
      result ({ data }) {
        this.form.username = data.user.username
        this.form.firstName = data.user.firstName
        this.form.lastName = data.user.lastName
      }
    }
  },
  data () {
    return {
      form: {
        username: '',
        password: '',
        firstName: '',
        lastName: ''
      },
      // ...
    }
  },
  methods: {
    // ...
  }
</code></pre>

<p>Je dois mentionner que j'ai vu des sujets plus ou moins liés mais cela ne résout pas mon problème.</p>

<p>Merci d'avance pour votre aide!</p></x-turndown>

1voto

sh0ber Points 6566

Modifiez vos chemins de route pour utiliser des paramètres. Par exemple :

{ path: '/utilisateur/:userId', name: 'UserFormView', component: UserForm, props: true }

Maintenant, l'application interprétera tout nombre suivant le chemin utilisateur/ en tant que propriété appelée userId. (props: true est important ici pour utiliser les paramètres en tant que propriétés.)

La seule autre modification que vous devez apporter est d'ajuster vos liens de routeur pour inclure également l'id (Ex. : http://localhost:8000/utilisateur/1) afin que lorsque la page est rafraîchie, il y ait un paramètre à lire.

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