Vuejs2使计数器保持最新状态

时间:2017-08-19 11:40:51

标签: vuejs2

我正在尝试使用pusher为聊天室中的用户列表动态更新计数器值。变量usersCountvue实例维护,并在模板中提供。 vue调试工具在下面的代码中将其显示为undefined。我没有将变量正确地传递给实例中的模板。

像这样调用

chat-player-list模板:

<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>

玩家全部列出并渲染OK,另外其他条件函数也能正常工作。只是usersCounter没有渲染。

我的chat.js代码包含主vue实例:

/**
 * 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);
                    });
            }
        }
    });
});

在我的模板chat-player-list.vue中,我有:

<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>

我错过了什么?谢谢!

1 个答案:

答案 0 :(得分:2)

数据不会自动传递给子组件,您需要手动将其声明为prop

  

每个组件实例都有自己独立的范围。这意味着您不能(也不应该)直接引用子组件模板中的父数据。可以使用props将数据传递给子组件。

更新

您应该像npm install -g sign-check sign-check 'path/to/file'

一样绑定usersCount

<chat-player-list ref="users" :users="users" :users-count="usersCount"></chat-player-list>是v-bind的简写语法。这意味着传递当前实例  将数据:a="b"作为名为b的道具添加到子组件。如果没有这个,即使存在a,子组件也无法接收它 所以只需添加prop:['a']即可。

正如Vamsi所提到的,usersCount应该以{{1​​}}传递,请参阅:https://vuejs.org/v2/guide/components.html#camelCase-vs-kebab-case