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

问题描述 投票:1回答:1

[我正在创建一个即时通讯工具作为Vue.js学习练习,但遇到了令人困惑的错误,其中作为道具传递的用于插槽化子组件访问的数组和对象正在变成字符串,并产生类似错误的错误:

[[Vue警告]:道具无效:道具“ messageGroup”的类型检查失败。期望的数组,得到的字符串值为“ [object Object],[object Object],[object Object],[object Object]”。

[[Vue警告]:无效的道具:道具“消息”的类型检查失败。期望的对象,得到的字符串值为“ [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(),
    } 
);

结果:enter image description here

vue.js vuejs2 web-component custom-element
1个回答
0
投票

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

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

我正在尝试在:props中传递json。

© www.soinside.com 2019 - 2024. All rights reserved.