为什么我的对象和数组道具变成子组件中的字符串?
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
我正在创建一个即时消息程序作为 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