in my vue.js application i have a component which children inside, which are either of component type "Test" or "AnotherComponent". The user can add one of those components by a button click and it will then be added at the end of the list of child components.
Each of these components should have a delete-button to remove the component from the list shown.
I added such a button to "AnotherComponent" and added an event emitter on click because I wanted to notify the parent component of the event so it will take care of removing the right component from the list. Is this approach correct at all?
This is the child component
<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>
This is the parent component:
<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>
Unfortunately in the parent component this event from th child does not get triggered at all. I am just starting with vue.js, so what am I doing wrong here? Thanks in advance!
delete-componentevent handler into div, not the component itself.'created'hook.