为什么我的对象和数组道具变成子组件中的字符串?

Why are my object and array props becoming strings in child components?

我正在创建一个即时消息程序作为 Vue.js 学习练习,但我遇到了一个混淆错误,其中作为 props 传递给有槽子组件访问的数组和对象正在变成字符串,并产生错误喜欢:

[Vue warn]: Invalid prop: type check failed for prop "messageGroup". Expected Array, got String with value "[object Object],[object Object],[object Object],[object Object]".

[Vue warn]: Invalid prop: type check failed for prop "message". Expected Object, got String with value "[object Object]".

传递原始类型作为子组件的属性按预期工作。 使用 :prop-name 或 v-bind:prop-name 传递对象和数组会产生字符串。

我该如何解决这个问题,或者我对正确的方法缺乏理解?

以下是组件的完整代码及其注册方式:

信使:

<template>
    <section id="messenger">
        <header>
            <h1>Test Conversation Window</h1>
        </header>
        <aside class="control-menu">
            Control Menu 
            <hr>
        </aside>
        <!-- The aggrieving section -->
        <main v-if="messageGroups.length" >
            <vue-message-group 
                v-for="(messageGroup, i) of messageGroups" 
                :key="i"
                v-bind:message-group="messageGroup"
                :username="messageGroup[0].username" >
                <vue-message 
                    v-for="message of messageGroup" :key="message.id"
                    v-bind:message="message" >
                </vue-message>
            </vue-message-group>
        </main>
        <!-- -- -->
        <aside class="participants">
            Participants
            <hr>
            <ul v-if="participants.length">
                <li v-for="(user, i) in participants" :key="i">
                    <img v-bind:src="user.avatar" v-bind:alt="user.username">
                    <span>{{ user.username }}</span>
                </li>
            </ul>
        </aside>
    </section>
</template>

<script>
export default {
    data() {
        return {
            participants: [],
            messageGroups: null,
        }
    },
    created() {
        this.getParticipants( [ 'john', 'karen' ] );
        this.messageGroups = this.groupMessages( this.testMessages() );
    },
    methods: {
        getParticipants: async function( users ) {
            this.url = 'http://*.*.*.*/api/user/';
            this.participants = await Promise.all( users.map( 
                async participant => 
                await this.getUserFromAPI( participant )
            ) );
        },
        getUserFromAPI: async function( username )
        {
            return await fetch( this.url + username )
                .then( data => data.json() )
                .then( data => data.data );
        },
        groupMessages: function( messages ) {
            let lastUsername = null;
            let groups = new Array();
            let group = null;
            for ( const message of messages )
            {
                if ( message.username !== lastUsername )
                {
                    group = new Array();
                    group.push( message );
                    groups.push( group );
                    lastUsername = message.username;
                }
                else
                {
                    group.push( message );
                }
            }
            return groups;
        },
        testMessages: function() {
            return [
                {
                    id: 0,
                    username: 'john',
                    message: 'TEST 1 message content.',
                    timestamp: '2020-05-20T23:09:13',
                },
                {
                    id: 1,
                    username: 'john',
                    message: 'TEST 2 message content.',
                    timestamp: '2020-05-20T23:09:13',
                },
                {
                    id: 2,
                    username: 'john',
                    message: 'TEST 3 message content.',
                    timestamp: '2020-05-20T23:09:13',
                },
                {
                    id: 3,
                    username: 'karen >:[',
                    message: 'TEST 4 message content.',
                    timestamp: '2020-05-20T23:09:13',
                },
                {
                    id: 4,
                    username: 'karen >:[',
                    message: 'TEST 5 message content.',
                    timestamp: '2020-05-20T23:09:13',
                },
                {
                    id: 5,
                    username: 'john',
                    message: 'TEST 6 message content.',
                    timestamp: '2020-05-20T23:09:13',
                },
                {
                    id: 6,
                    username: 'karen >:[',
                    message: 'TEST 7 message content.',
                    timestamp: '2020-05-20T23:09:13',
                },
                {
                    id: 7,
                    username: 'karen >:[',
                    message: 'TEST 8 message content.',
                    timestamp: '2020-05-20T23:09:13',
                },
                {
                    id: 8,
                    username: 'karen >:[',
                    message: 'TEST 9 message content.',
                    timestamp: '2020-05-20T23:09:13',
                },
                {
                    id: 9,
                    username: 'karen >:[',
                    message: 'TEST 10 message content.',
                    timestamp: '2020-05-20T23:09:13',
                },
            ];
        },
    },
}
</script>

消息组:

<template>
    <figure class="message">
        <main>
            <span>{{ username }}</span>
            <slot></slot>
        </main>
    </figure>
</template>
<script>
export default {
    props: {
        username: String,
        messageGroup: Array,
    },
}
</script>

留言:

<template>
    <div class="message">
        <span class="line">{{ message.message }}</span>
        <div class="timestamp">{{ message.timestamp }}</div>
    </div>
</template>
<script>
export default {
    props: {
        message: Object,
    },
}
</script>

App.js:

import Vue from 'vue'

import vueCustomElement from 'vue-custom-element'
/*
* See: https://github.com/karol-f/vue-custom-element
*/

Vue.use(vueCustomElement);

Vue.config.ignoredElements = [
    'vue-messenger',
    'vue-message-group',
    'vue-message',
];


import VueMessenger from './components/VueMessenger.vue'
const messengerStyles = require( '!css-loader!sass-loader!./components/css/VueMessenger.scss' );
Vue.customElement( 
    'vue-messenger', 
    VueMessenger, 
    {
        shadow: true,
        shadowCss: messengerStyles.toString(),
    } 
);

import VueMessageGroup from './components/VueMessageGroup.vue'
const messageGroupStyles = require( '!css-loader!sass-loader!./components/css/VueMessageGroup.scss' );
Vue.customElement( 
    'vue-message-group', 
    VueMessageGroup, 
    {
        shadow: true,
        shadowCss: messageGroupStyles.toString(),
    } 
);

import VueMessage from './components/VueMessage.vue'
const messageStyles = require( '!css-loader!sass-loader!./components/css/VueMessage.scss' );
Vue.customElement( 
    'vue-message', 
    VueMessage, 
    {
        shadow: true,
        shadowCss: messageStyles.toString(),
    } 
);

结果:

问题源于我将 Vue 组件注册为浏览器的自定义元素;浏览器要求所有元素属性都是字符串,因此强制对象和数组。

最简单的解决方法似乎是传递对象属性而不是对象本身。

我正在尝试在 :props.

中传递 json