【问题标题】:Passing variables from within VueJS components从 VueJS 组件中传递变量
【发布时间】:2020-06-20 03:08:20
【问题描述】:

我是 VueJs 和 Laravel 的新手。我正在尝试按照this 教程构建一个聊天应用程序,我的问题是我无法将 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}
}

Conversation.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();
        }
    }
}

请让我知道我在这里缺少什么。

【问题讨论】:

  • 你确定这个错误信息不是来自初始的 selectedContect 状态,它等于 null 吗?
  • 我想是这样,因为我放了两个打印语句,一个在 ChatApp.vue 另一个在 Conversation,vue 中,后来打印出来很奇怪,或者至少对我来说无论如何,是不是应该先安装 ChatApp,然后再安装其他组件,这样如果我们传递变量,它应该能够识别它们
  • 您可以尝试
  • 您似乎没有收到来自 ContactsList 的任何联系人。在 startConversationWith 方法中,你能 console.log(contact) 吗?和/或提供 ContactsList 组件的代码

标签: javascript typescript vue.js laravel-5


【解决方案1】:

因为您将其配置为 Object 但您在初始状态下将其声明为 null

  selectedContact: null

那应该是object

我猜它应该看起来像这样:

  selectedContact: {
       id:0
  }

【讨论】:

  • officer.js?id=129a142a656d58ac6230:31472 [Vue warn]: Invalid prop: type check failed for prop "contact". Expected Object, got Function found in ---&gt; &lt;Conversation&gt; at resources/js/officer/components/Conversation.vue &lt;ChatApp&gt; at resources/js/officer/components/ChatApp.vue &lt;Root&gt; 错误
  • 错误很明显:Expected Object, got Function 你传递的是函数而不是对象。
  • 我尝试了第二个,但它没有在控制台上打印任何内容。它只是打印conversation: [object Object]
  • 我尝试了你给出的第一个解决方案,然后出现了这个错误
【解决方案2】:

我解决了这个问题。 这是由于 axios.get() 响应的事情。几分钟后它正在从数据库中获取数据,并且 Conversation.vue 和 ContactList.vue 立即安装,因此它们没有获取数据。 在我朋友的帮助下,只有当 axios 从数据库中获取所有联系人列表并且第一个联系人已传递给 Conversation.vue 组件(即使用组件的 v-if 属性)时,才通过加载组件来解决此问题。

【讨论】:

    猜你喜欢
    • 2019-09-15
    • 1970-01-01
    • 2017-07-20
    • 1970-01-01
    • 2020-02-02
    • 2019-09-11
    • 2017-11-09
    • 2018-08-29
    • 1970-01-01
    相关资源
    最近更新 更多