[英]vue pass custom component as a property to parent component
我还没有看到其他试图回答我正在做的事情的问题,我不确定是否只是我没有在寻找正确的措辞,所以我会解释发生了什么。
我正在尝试开发一个界面,用户可以在其中使用 vue 拖动或输入图像。 我还制作了一个名为Card
的组件,它有点像卡片对象的 vue 和 bulma。 Card
组件有两个props
, title
和content
。 当您要填写的title
和content
属性是预加载的文本或图像数据时,使用起来非常简单。
但是,我想做的是在Card
内放置另一个vue 组件(来自npm上的vue-picture-input
的PictureInput
组件)。 我试图通过将它作为content
道具传递来做到这一点。 我已经阅读了关于反应性道具和动态组件的 vue 文档,但都没有真正谈论这个用例。
代码:
卡片.vue:
<template>
<div class="card is-size-7-mobile is-fluid">
<div class="card-header">
<a class="card-header-title">
<span class="is-info">{{this.title}}</span>
</a>
<span v-if="this.isExpanable">
<a class="card-header-icon card-toggle">
<span class="icon" @click="arrowClick">
<span v-if="!this.open">
<font-awesome-icon :icon="['fas', 'angle-down']"></font-awesome-icon>
</span>
<span v-else>
<font-awesome-icon :icon="['fas', 'angle-up']"></font-awesome-icon>
</span>
</span>
</a>
</span>
</div>
<slide-up-down :active="this.open" :duration="400" v-if="this.isExpanable">
<div v-if="this.open" class="card-content is-size-7-mobile">
<div class="content">{{this.content}}</div>
</div>
</slide-up-down>
<div v-else>
<div class="content">{{this.content}}</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
open: false
};
},
props: {
title: "",
content: null,
isExpanable: false
},
methods: {
arrowClick(event) {
this.open = !this.open;
}
}
};
</script>
<style scoped>
.card {
border-radius: 1em;
background-color: transparent !important;
border-color: transparent !important;
}
.card-header {
box-shadow: transparent;
}
</style>
图像输入.vue:
<template>
<div class="content">
<Card :title="makeCardTitle()" :content="makeCardContent()"/>
</div>
</template>
<script>
import PictureInput from 'vue-picture-input';
import Card from './Card';
import Vue from 'vue';
export default {
name: 'ImageInput',
components: {
PictureInput,
Card
},
props: {
idx:{
type:Number,
default: 0
}
},
data() {
return {
pictureComponent: "PictureInput"
}
},
methods: {
makeCardTitle: function(){
return "page ".concat(String(this.idx))
},
makeCardContent: function(){
var PictureInputClass = Vue.extend(PictureInput);
var pictureInputInstance = new PictureInputClass();
return pictureInputInstance
}
}
}
</script>
<style scoped>
</style>
正如您在ImageInput.vue
代码中看到的那样,我尝试动态构造PictureInput
对象并将其作为道具content
传递给Card
但它不起作用,我收到两个错误,一个是Card
中的“循环对象值”另一个是PictureInputClass
对象没有toJSON
方法,我猜测 vue 框架的某些部分是期望的。 我也尝试过这样做: <Card :title="makeCardTitle()" :content="PictureInput"/>
,但我最终得到有关PictureInput
未定义但在渲染期间被引用的错误。 也许我可以将content
更改为命名的<slot></slot>
但我不确定这是否也是我想要的。
我经历这一切的原因是,我真的很欣赏 Vue 是如何被设计成在创建界面时允许组件被重用和重新集成的。 我显然可以从Card
中获取(大部分)模板并针对这种情况重新配置它,但我想看看是否有更简单的方法可以让PictureInput
组件成为Card
组件的子组件。
我会使用插槽将 PictureInput 组件放入 Card 组件中。 为了简化示例,我删除了一些 HTML。
Card.vue
<template>
<div class="card is-size-7-mobile is-fluid">
<div class="card-header">
<a class="card-header-title">
<!-- Don't need to use "this" keyword inside the template,
it is implied that the context is already "this" -->
<span class="is-info" @click="isExpanable = !isExpanable">{{title}}</span>
</a>
</div>
<div v-if='isExpanable'>
<slot/> <!-- Slot where the <PictureInput/> will be inserted -->
</div>
</div>
</template>
<script>
export default {
data() {
return {
isExpanable: false, // internal state to manage the open/close toggle
}
},
props: {
title: String, // Define the data type
}
};
</script>
<style scoped>
.card {
border-radius: 1em;
background-color: transparent !important;
border-color: transparent !important;
}
.card-header {
box-shadow: transparent;
}
</style>
图像输入.vue
<template>
<div class="content">
<Card :title="makeCardTitle">
<PictureInput/>
</Card>
</div>
</template>
<script>
import PictureInput from 'vue-picture-input';
import Card from './Card';
export default {
name: 'ImageInput',
components: {
PictureInput,
Card
},
props: {
idx:{
type:Number,
default: 0
}
},
computed: {
// Should be a computed property since we are creating data from internal data "idx"
makeCardTitle: function(){
return "page ".concat(String(this.idx));
}
}
}
</script>
希望这会引导您朝着正确的方向前进。 此外,您不必使用 Vue.extend(PictureInput) 进行实例化。 通常,您需要做的就是将其添加到组件选项键中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.