在我的vue.js应用程序中,我有一个内部带有子组件的组件,这些子组件属于组件类型“ Test”或“ AnotherComponent”。 用户可以通过单击按钮添加这些组件之一,然后将其添加到子组件列表的末尾。
每个组件都应具有一个删除按钮,以从显示的列表中删除该组件。
我在“ AnotherComponent”中添加了这样的按钮,并且在单击时添加了事件发射器,因为我想将事件通知给父组件,因此它将负责从列表中删除正确的组件。这种方法完全正确吗?
这是子组件
<template>
<div>
<div class="container">
<b-card
title="Card Title"
class="mb-2"
>
<b-card-text>
This card has some text and it different from the other component.
Also there is a nice picture.
</b-card-text>
<button
type="button"
class="btn btn-secondary"
v-on:click="deleteComponent()"
>
x
</button>
</b-card>
</div>
</div>
</template>
<script>
export default {
name: 'AnotherComponent',
data() {
return {
};
},
methods: {
deleteComponent(event) {
this.$emit('delete-component', this.$vnode.key);
},
},
};
</script>
这是父组件:
<template>
<div>
<div class="container">
<h1> This is my first layout page </h1>
<alert :message=alertText></alert>
<button
type="button"
class="btn btn-primary"
v-on:click="addComponent('test')"
>
add component 1
</button>
<button
type="button"
class="btn btn-primary"
v-on:click="addComponent('another')"
>
add component 2
</button>
<div class="row">
<template
v-for="block in content.body">
<div class="col-3" v-bind:key="`col-${block._uid}`">
<component
:is="block.component"
:block="block"
:key="block._uid"
v-on:delete-component="onDeleteChildComponent($event)">
</component>
</div>
</template>
</div>
</div>
</div>
</template>
<script>
/* eslint-disable vue/no-unused-components */
import axios from 'axios';
import TestComponent from './TestComponent.vue';
import AnotherComponent from './AnotherComponent.vue';
import Alert from './Alert.vue';
export default {
name: 'FirstPage',
data() {
return {
alertText: 'this is a test!',
content: {
body: [], /* holds the array of objects that are components */
},
};
},
components: {
alert: Alert,
test: TestComponent,
another: AnotherComponent,
// AnotherComponent,
},
methods: {
getComponents() {
const path = 'http://localhost:8080/components';
axios.get(path)
.then((res) => {
console.log('res.data');
this.content.body = res.data.components;
})
.catch((error) => {
// eslint-disable-next-line
console.error(error);
});
},
addComponent(componentType) {
const path = 'http://localhost:8080/components';
const payload = {
component: componentType,
headline: 'Bar',
};
axios.post(path, payload)
.then(() => {
this.getComponents();
this.message = 'Component added!';
})
.catch((error) => {
// eslint-disable-next-line
console.log(error);
this.getComponents();
});
},
},
onDeleteChildComponent(id) {
console.log('delete child');
console.log(id);
},
created() {
console.log('fetching components from backend');
this.getComponents();
},
};
</script>
不幸的是,在父组件中,这个子事件根本没有被触发。 我只是从vue.js开始,所以我在这里做错了什么?提前致谢!
答案 0 :(得分:1)
您正在发出'deleteComponent'
并在听'delete-component'
。此转换不适用于事件注册,仅用于转换组件名称。
https://vuejs.org/v2/guide/components-custom-events.html
尝试以下方法:
// child component
methods: {
deleteComponent(event) {
this.$emit('delete-component', this.$vnode.key);
},
},
编辑:正如Eldar在评论中正确指出的那样,您的听众也在听错误的元素。将侦听器移至动态组件,如下所示:
// parent component
<!-- template tags not necessary unless you're trying to render more than 1 root node per v-for element -->
<div class="col-3" v-for="block in content.body" :key="`col-${block._uid}`">
<component
@delete-component="onDeleteChildComponent($event)"
:is="block.component"
:block="block"
:key="block._uid">
</component>
</div>
编辑2:您尝试收听的方法未在您的方法中列出,但级别太高。跟踪您的括号! ;)
methods: {
getComponents() {
...
},
addComponent(componentType) {
...
},
},
onDeleteChildComponent(id) {
console.log('delete child');
console.log(id);
},
应为:
methods: {
getComponents() {
...
},
addComponent(componentType) {
...
},
onDeleteChildComponent(id) {
console.log('delete child');
console.log(id);
},
},