我还没有看到其他尝试回答我在做什么的问题,我不确定是否只是我没有在寻找正确的语言,所以我将解释发生的情况。
我正在尝试开发一个界面,用户可以使用vue拖动或输入图像。我也有一个名为Card
的组件,它对于类似卡片的对象有些虚假的东西。 Card
组件有两个props
,title
和content
。当您要填充title
和content
属性的内容是预加载的文本或图像数据时,使用起来非常简单。
但是,我想做的是在Card
内放置另一个 vue组件(npm上PictureInput
的{{1}}组件) 。我正在尝试通过将其作为vue-picture-input
道具来实现。我已经阅读了reactive props和dynamic components上的vue文档,但都没有真正谈论这个用例。
代码:
Card.vue:
content
ImageInput.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>
您可以使用 <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
对象,并将其作为prop PictureInput
传递给content
,但是它没有正常工作时,我遇到两个错误,一个是Card
中的“循环对象值”,另一个是Card
对象没有PictureInputClass
方法,我猜这是Vue框架的某些部分预期。我也尝试过这样做:
toJSON
,但是最终我得到关于<Card :title="makeCardTitle()" :content="PictureInput"/>
是如何定义的,但在渲染过程中如何引用的错误。也许我可以将PictureInput
更改为命名的content
,但是我不确定这是否也是我想要的。
我要经历所有这些的原因是,我非常欣赏Vue在创建接口时如何设计为允许组件重新使用和彼此重新集成。我显然可以从<slot></slot>
中提取(大部分)模板,然后针对这种情况重新配置它,但是我想看看是否有一种更简单的方法来使Card
组件成为PictureInput
组件。
答案 0 :(得分:1)
我将使用插槽将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>
ImageInput.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)实例化。通常,您要做的就是将其添加到components选项键中。