2017-08-19 2 views
0

Ich versuche, einen Zählerwert dynamisch für eine Liste von Benutzern in einem Chatroom mit pusher aktualisiert zu halten. Die Variable usersCount wird von der Instanz vue verwaltet und in einer Vorlage bereitgestellt. Das vue Debug-Tool zeigt es als undefined in dem folgenden Code. Ich übergebe die Variable nicht korrekt an die Vorlage von der Instanz.Vuejs2 Counter auf dem neuesten Stand

chat-player-list Vorlage wird wie folgt aufgerufen:

<div class="modal-body" id="sidebar-chat"> 

    <div class="row"> 
     <chat-player-list ref="users" :users="users"></chat-player-list> 
    </div> 

    <hr/> 

    <div class="row"> 
     <div class="col-xs-12"> 
      <chat-player-messages ref="messages" :messages="messages"></chat-player-messages> 
      <h5>Enemies chit chat</h5> 
      <chat-player-form v-on:chatmessagesent="addMessage" :player="{{ Auth::user() }}"></chat-player-form> 
     </div> 
    </div> 

</div> 

Die Spieler alle Liste und machen OK, und zusätzlich der Rest der bedingten Funktionen OK arbeiten. Nur die usersCounter nicht rendern.

Mein chat.js Code enthält die Haupt vue Beispiel:

/** 
* Set up Vue components for chat 
*/ 
$(document).ready(function() 
{ 
    Vue.component('chat-player-list', require('../components/chat-player-list.vue')); 
    Vue.component('chat-player-messages', require('../components/chat-player-messages.vue')); 
    Vue.component('chat-player-form', require('../components/chat-player-form.vue')); 

    var chatPlayer = new Vue({ 
     el: '#sidebar-chat', 

     data: function() { 
      return { 
       game: game, 
       messages: [], 
       users: [], 
       usersCount: 0 
      }; 
     }, 

     created() { 
      this.fetchPlayers(); 
      this.fetchMessages(); 

      Echo.join(chat_channel) 
       .here((users) => { 
        $.each(users, function(index, value) { 
         $('i#online-' + users[index].id).addClass('faa-ring animated player-online'); 
        }); 
        this.usersCount = users.length; 
       }) 
       .joining((user) => { 
        $('i#online-' + user.id).addClass('faa-ring animated player-online'); 
        this.usersCount = this.usersCount + 1; 
       }) 
       .leaving((user) => { 
        $('i#online-' + user.id).removeClass('faa-ring animated player-online'); 
        this.usersCount = this.usersCount - 1; 
       }) 
       .listen('ChatMessageSent', (e) => { 
        this.messages.unshift({ 
         message: e.message.message, 
         player: e.player 
        }); 
       }); 
     }, 

     methods: { 
      fetchPlayers() { 
       this.users = game.progress.status.players_status; 
      }, 

      fetchMessages() { 
       axios.get(chat_get_route) 
        .then(response => { 
         this.messages = response.data; 
        }); 
      }, 

      addMessage(message) { 
       this.messages.unshift(message); 

       this.$nextTick(() => { 
        this.$refs.messages.scrollToTop(); 
       }); 

       axios.post(chat_send_route, message) 
        .then(response => { 
         console.log(response.data); 
        }); 
      } 
     } 
    }); 
}); 

In meiner Vorlage chat-player-list.vue ich habe:

<template> 
    <div class="col-xs-12"> 
     <h5>Enemies online</h5> 
     <span id="no-online-players" class="player-label pull-right">{{ usersCount }}</span> 

     <hr/> 

     <table id="new-game-opponents" class="new-game-opponents"> 
      <tbody> 
      <tr v-for="(user, index) in users" :key="index" :class="[isPlayerTurn(user.owner_id) ? playerTurnClass : '']"> 
       <td class="player_number"> 
        <div :class="['opponent player-' + index++]" v-once>{{ index++ }}</div> 
       </td> 
       <td class="player-avatar"> 
        <img :id="['player_avatar-' + user.owner_id]" class="setup_player_avatar" :src="[user.avatar]" v-once/> 
       </td> 
       <td class="player-name"> 
        <div :id="['player_nickname-' + user.owner_id]" v-once> 
         {{ user.nickname }}&nbsp;&nbsp; 
         <i :class="[isThisPlayer(user.owner_id) ? 'fa fa-user-circle-o' : 'hidden']" aria-hidden="true" style="color:DarkOrange;"></i> 
        </div> 
       </td> 
       <td class="player-status text-right"> 
        <div v-if="isPlayerTurn(user.owner_id)"> 
         <span :id="['player_turn-' + user.owner_id]" class="stage-label pull-right">{{ progress }}</span> 
        </div> 
        <div v-else> 
         <i class="fa fa-clock-o" aria-hidden="true" style="margin-right:5px;"></i> 
        </div> 
       </td> 
       <td class="player-status text-right"> 
        <i class="fa fa-comments" :id="['online-' + user.owner_id]" aria-hidden="true"></i> 
       </td> 
       <td class="player-status text-right"> 
        <div v-if="isHuman(user.owner_id)"> 
         <i class="fa fa-desktop" aria-hidden="true"></i> 
        </div> 
        <div v-else> 
         <i class="fa fa-user" aria-hidden="true" style="margin-right:2px;"></i> 
        </div> 
       </td> 
      </tr> 
      </tbody> 
     </table> 
    </div> 
</template> 

<script> 
    export default { 
     props: ['users', 'usersCount'], 

     data: function() { 
      return { 
       playerTurnClass: 'next-player-turn', 
       nextPlayerId: game.progress.next_player_id, 
       progress: game.progress.status.turn_status.current_stage, 
       myPlayerId: my_player.id 
      } 
     }, 

     methods: { 
      isPlayerTurn(thisUserId) { 
       return thisUserId == this.nextPlayerId; 
      }, 
      isThisPlayer(thisUserId) { 
       return thisUserId == this.myPlayerId; 
      }, 
      isHuman(thisUserOwnerId) { 
       return thisUserOwnerId != 'ai'; 
      } 
     } 
    }; 
</script> 

Was habe ich verpasst? Vielen Dank!

+0

Können Sie zeigen, wie Sie 'Chat-Spieler-list' in Rootinstanz Element verwenden und wie sind vorbei Sie die Stütze –

+0

@Vamsi Krishna Hi, ich habe hinzugefügt wie du gefragt hast. Lass es mich wissen, wenn ich es falsch verstanden habe. Vielen Dank! – TheRealPapa

+0

Sie übergeben nicht die 'usersCount Prop –

Antwort

2

Die Daten werden nicht automatisch an die untergeordnete Komponente übergeben, Sie müssen sie manuell als prop deklarieren.

Jede Komponenteninstanz hat ihren eigenen isolierten Bereich. Dies bedeutet, dass Sie nicht direkt auf die übergeordneten Daten in der Vorlage einer untergeordneten Komponente verweisen können (und sollten). Daten können mithilfe von Requisiten an untergeordnete Komponenten übergeben werden.

Aktualisiert

Sie usersCount wie <chat-player-list ref="users" :users="users" :users-count="usersCount"></chat-player-list>

:a="b" binden sollte, ist eine Abkürzung Syntax von v-bind. Das bedeutet, dass die Daten b der aktuellen Instanz an die untergeordnete Komponente als Prop mit der Bezeichnung a übergeben werden. Ohne dies kann die untergeordnete Komponente es nicht empfangen, obwohl prop:['a'] vorhanden ist.
Fügen Sie einfach :users-count="usersCount" hinzu.

Wie Vamsi erwähnt, usersCount sollte als users-count geben werden, siehe: https://vuejs.org/v2/guide/components.html#camelCase-vs-kebab-case

+0

Hallo @ Choasia, aber ich gebe es in einer Requisite, nein? 'user' Array wird durch OK übergeben. Auch die Änderungen an 'usersCount' passieren in der 'vue'-Instanz und nicht in der Vorlage – TheRealPapa

+0

@TheRealPapa würden Sie den js-Code Ihrer Elternvorlage und untergeordneten Komponente angeben? – choasia

+0

Hallo @choasia Ich aktualisierte die Frage mit dem gesamten Code angefordert. 'usersCount' wird in' chat-players.js' aktualisiert (Haupt-'vue'-Instanz) und es wird in' chat-player-list.vue' Vorlage angezeigt – TheRealPapa

Verwandte Themen