Передача переменных из компонентов VueJS - PullRequest
2 голосов
/ 07 марта 2020

Я новичок в VueJs и Laravel. Я пытаюсь создать приложение для чата, следуя этому руководству, и моя проблема в том, что я не могу передать переменную CONTACT (тип объекта) из ChatApp. vue в Conversation . vue. Консоль выдает эту ошибку

[Vue warn]: Invalid prop: type check failed for prop "contact". Expected Object, got Null 
found in ---> <MessageFeed> at resources/js/officer/components/MessageFeed.vue
   <Conversation> at resources/js/officer/components/Conversation.vue
     <ChatApp> at resources/js/officer/components/ChatApp.vue
       <Root>

. Сначала переменная должна пройти через ChatApp в Conversation, а затем в MessageFeed. Я попытался напечатать его на консоли, в ChatApp. vue, он напечатал свойство переменной, то есть имя, но когда я пытаюсь напечатать его в Conversation. vue, он говорит, что он нулевой, а также выдает ошибку выше.

см. Код ниже:

ChatApp. vue

<template>
<div class="chat-app">
    <Conversation :contact="selectedContact" :messages="messages" @new="saveNewMessage"/>
    <ContactsList :contacts="contacts" @selected="startConversationWith"/>
</div>
</template>
<script>
import Conversation from "./Conversation";
import ContactsList from "./ContactsList";
const axios = require('axios');
export default {
    props: {
        user: {
            type: Object,
            required: true
        }
    },
    data() {
        return {
            selectedContact: null,
            messages: [],
            contacts: []
        }
    },
    mounted() {
        Echo.private(`messages.${this.user.id}`)
            .listen('NewMessage', (e) => {
                this.handleIncoming(e.message);
            });
        console.log(this.user);
        axios.get('/officer/contacts')
            .then((response) => {
                this.contacts = response.data;
                console.log("chatapp1: " + this.contacts[0].name);
            })
            .catch((error) => {
                // handle error
                console.log(error);
            });
    },
    methods: {
        startConversationWith(contact) {
            axios.get(`/officer/conversation/${contact.id}`)
                .then((response) => {
                    this.message = response.data;
                    this.selectedContact = contact;
                    console.log("chatapp: " + this.selectedContact.name);
                });
        },
        saveNewMessage(message) {
            this.messages.push(message);
        },
        handleIncoming(message) {
            if (this.selectedContact && message.from === this.selectedContact.id) {
                this.saveNewMessage(message);
                return;
            }
            this.updateUnreadCount(message.from_contact, false);
        },
        updateUnreadCount(contact, reset) {
            this.contacts = this.contacts.map((single) => {
                if (single.id !== contact.id) {
                    return single;
                }
                if (reset)
                    single.unread = 0;
                else
                    single.unread += 1;
                return single;
            })
        }
    },
    components: {Conversation, ContactsList}
}

Разговор. vue

<template>
<div class="conversation">
    <h1>{{ contact ? contact.name : 'Select a Contact' }}</h1>
    <MessagesFeed :contact="contact" :messages="messages"/>
    <MessageComposer @send="sendMessage"/>
</div>
</template>
<script>
import MessagesFeed from './MessageFeed';
import MessageComposer from './MessageComposer';
export default {
    props: {
        contact: {
            type: Object,
            default: null
        },
        messages: {
            type: Array,
            default: []
        }
    },
    mounted() {
        console.log("conversation: "+this.contact);
    },
    methods: {
        sendMessage(text) {
            if (!this.contact) {
                return;
            }
            console.log(text);
            axios.post('/conversation/send', {
                contact_id: this.contact.id,
                text: text
            }).then((response) => {
                this.$emit('new', response.data);
            })
        }
    },
    components: {MessagesFeed, MessageComposer}
}

MessageFeed. vue

<template>
<div class="feed" ref="feed">
    <ul v-if="contact">
        <li v-for="message in messages" :class="`message${message.to == contact.id ? 'sent' : 'received'}`"
            :key="message.id">
            <div class="text">
                {{message.text}}
            </div>
        </li>
    </ul>
</div>
</template>
<script>
export default {
    props: {
        contact: {
            type: Object,
            required: true
        },
        messages: {
            type: Array,
            required: true
        }
    },
    methods: {
        scrollToBottom() {
            setTimeout(() => {
                this.$refs.feed.scrollTop = this.$refs.feed.scrollHeight - this.$refs.feed.clientHeight;
            }, 1);
        }
    },
    watch: {
        contact(contact) {
            this.scrollToBottom();
        },
        messages(messages) {
            this.scrollToBottom();
        }
    }
}

пожалуйста, дайте мне знать, что я Я здесь скучаю.

Ответы [ 2 ]

0 голосов
/ 08 марта 2020

Я исправил проблему. Это было связано с ответом ax ios .get (). Через несколько минут он извлекал данные из базы данных, и Conversation. vue и ContactList. vue монтировались немедленно, поэтому они не получали данные. С помощью моего друга это было исправлено путем загрузки компонента только тогда, когда ax ios получил весь список контактов из базы данных, а самый первый контакт был передан компоненту Conversation. vue, т.е. с использованием свойства v-if компонент.

0 голосов
/ 07 марта 2020

Поскольку вы сконфигурировали его как объект, но вы объявили его в начальном состоянии как null

  selectedContact: null

Это должно быть object

Это должно выглядеть примерно так это я думаю:

  selectedContact: {
       id:0
  }
...