2017-09-06 1 views
1

J'essaie d'utiliser Vuejs avec le Vue-Socket.io plugin et j'ai une question concernant la façon correcte de passer le socket entre les composants.Vuejs et vue-socketio: comment passer l'instance de socket aux composants

Idéalement, je ne souhaite utiliser qu'une seule socket dans l'ensemble de mon application. Je veux donc instancier le socket dans l'instance racine et le transmettre ensuite aux composants qui en ont besoin en tant que 'prop'. Est-ce la bonne façon de le faire?

Si oui, qu'est-ce que je fais de mal? L'erreur que je reçois est TypeError: this.socket.emit is not a function alors je ne passe probablement pas l'objet socket correctement.

Le composant à l'aide du socket a le script suivant

<script> 
    export default { 
    name: 'top', 
    props: ['socket'], 
    data() { 
     return { 
     Title: 'My Title' 
     } 
    }, 
    methods: { 
     button_click: function (val) { 
     // This should emit something to the socketio server 
     console.log('clicking a button') 
     this.socket.emit('vuejs_inc', val) 
     } 
    } 
    } 
</script> 

Mon initialisation du composant racine ressemble à ceci:

import Vue from 'vue' 
import VueSocketio from 'vue-socket.io' 
import App from './App' 
import router from './router' 

Vue.use(VueSocketio, 'http://127.0.0.1:5000') 
Vue.config.productionTip = false 
/* eslint-disable no-new */ 
new Vue({ 
    el: '#app', 
    router, 
    template: '<App socket="this.$socket"/>', 
    components: {App}, 
    sockets: { 
    connect: function() { 
     console.log('Vuejs socket connected.') 
    }, 
    from_server: function (val) { 
     console.log('Data from server received: ' + val) 
    } 
    } 
}) 

Et App passe ensuite la prise via

<top socket="this.socket"></top> 

NB: Je sais que je pourrais aussi mettre l'instanciation de socket dans le composant qui en a besoin (dans ce cas: en haut), ou je pourrais accéder à l'objet socket du composant racine via this.$root.$socket, mais je ne veux pas faire non plus, parce que

  • Comme indiqué plus haut, je pourrais vouloir utiliser la prise dans d'autres composants
  • Je ne veux pas seulement de prendre un objet socket est là dans l'instance racine

essentiellement, je veux faire les choses d'un point de vue architectural.

+0

je passai l'instance de prise de l'instance racine dans l'instance App via 'ce socket' $, donc je ne devrais pas être en mesure. juste pour passer 'this.socket' de App. –

Répondre

3

Il n'y a pas besoin de passer quelque chose. Le plugin Vue-Socket.io makes the socket available sur chaque composant (et Vue) via this.$socket.

Je pense que votre code fonctionnerait, sauf pour le fait que vous ne semblez pas liaison le socket.

<top socket="this.socket"></top> 

devrait être

<top :socket="socket"></top> 

La première ligne ci-dessus prise vient de mettre à la chaîne "this.socket". La seconde définira la propriété sur le résultat de l'expression, this.socket.

Vous devez également modifier le modèle pour la Vue:

<App :socket="$socket"/> 
+0

Mais est-ce aussi la bonne façon de l'utiliser? Je pense qu'être déclaratif dans une définition de composant (en termes de ce qui devrait être là) est une bonne chose, c'est pourquoi je voulais passer explicitement l'instance de socket. –

+0

@random_error C'est de la même manière que Vuex et VueRouter (implémentant une propriété $ store et $ router respectivement) et ce sont des plugins officiels. Vous pourriez faire valoir que c'est la «bonne façon».Une alternative serait d'utiliser l'intégration des plugins avec Vuex (si vous l'utilisez) et d'envoyer des actions pour envoyer/recevoir des messages. – Bert

+1

Point pris, mais disons que je voulais réutiliser mon composant, ou faire comprendre à d'autres personnes en réutilisant le composant qu'il attend une connexion socket-io, quelle serait la bonne façon de procéder à ce sujet? Le magasin vuex $ et VueRouter sont fournis avec Vue, donc on peut s'attendre à ce qu'ils soient là, mais le plugin socketio n'est pas forcément là. Je suis peut-être en train de penser à cela, car je suis nouveau à Vue, j'essaie juste de mettre en œuvre un design clair et concis. –