【发布时间】:2020-05-25 05:40:11
【问题描述】:
我正在创建一个即时通讯工具作为 Vue.js 学习练习,我遇到了一个令人困惑的错误,其中数组和对象作为 props 传递给有槽的子组件访问正在变成字符串,并产生类似的错误:
[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(),
}
);
【问题讨论】:
-
我要做的第一件事是将
messageGroups定义为一个空数组,而不是null。除此之外,我无法重现这一点。在某处(不在上面的代码中),messageGroup中的数组正在转换为字符串(通过.toString()) -
这就是全部代码。
-
这里看起来不错~jsfiddle.net/eLsy6cgx。一定和 vue-custom-elements 的事情有关
标签: vue.js vuejs2 web-component custom-element