programing

오브젝트 및 어레이 소품이 아이 컴포넌트의 문자열이 되는 이유는 무엇입니까?

copysource 2022. 8. 10. 21:16
반응형

오브젝트 및 어레이 소품이 아이 컴포넌트의 문자열이 되는 이유는 무엇입니까?

Vue.js 학습 연습으로 인스턴트 메신저를 만들고 있는데 슬롯된 하위 컴포넌트의 소품으로 전달된 배열과 객체가 문자열이 되어 다음과 같은 오류가 발생합니다.

[Vue warn] :잘못된 제안: "messageGroup" 제안의 형식을 확인하지 못했습니다.어레이가 필요한데 값이 [개체], [개체], [개체], [개체], [개체]인 문자열이 필요합니다.

그리고.

[Vue warn] :잘못된 제안: "메시지" 제안의 형식을 확인하지 못했습니다.개체여야 합니다. 값이 "개체"인 문자열을 받았습니다.

기본형을 아이 컴포넌트의 소품으로 전달하면 예상대로 작동합니다.: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 컴포넌트를 브라우저에 커스텀 요소로 등록하기 때문에 발생합니다.브라우저에서는 모든 요소 속성이 문자열이어야 하므로 오브젝트와 어레이가 강제됩니다.

가장 간단한 해결 방법은 개체 자체 대신 개체 속성을 전달하는 것입니다.

저는 json을 :props로 패스하는 실험을 하고 있습니다.

언급URL : https://stackoverflow.com/questions/61996436/why-are-my-object-and-array-props-becoming-strings-in-child-components

반응형