2๐
Try not to do direct DOM manipulation if you can. There is almost always a better way with Vue. In your case, a simple array can hold true/false values for conditionally displaying a chart underneath your add/remove buttons. The buttons toggle the appropriate array value, and the chart only displays if that value is true using v-if
<template>
<div class="monitor-container">
<div class="monitor_interface-chart-container" v-for="index in 6" :key="index">
<i @click="addChart(index)" class="pi pi-plus-circle new_chart-icon">click me</i>
<i @click="removeChart(index)" class="pi pi-minus-circle">remove me</i>
<BaseChart v-if="chartArray[index]" />
</div>
</div>
</template>
<script>
import 'primeicons/primeicons.css';
import BaseChart from '@/components/charts/BaseChart.vue'
export default {
components: {
BaseChart,
},
data() {
return {
chartArray: [],
};
},
methods: {
addChart(index) {
this.$set(this.chartArray, index, true);
},
removeChart(index) {
this.$set(this.chartArray, index, false);
},
},
};
</script>
The this.$set()
syntax comes from Vue 2โs method for updating array values by index while maintaining reactivity
1๐
in my opinion, one of the best solutions is to create an array with graphs, the elements of which will contain a flag that allows you to adjust the display of each graph.
The final version will look approximately like this.
<template>
<div class="monitor-container">
<div
class="monitor_interface-chart-container"
v-for="chart in charts"
:key="chart.id"
>
<BaseChart v-if="chart.isShown" />
<i
v-if="!chart.isShown"
@click="addChart(chart.id)"
class="pi pi-plus-circle new_chart-icon"
>+</i
>
<i
v-else
@click="removeChart(chart.id)"
class="pi pi-plus-circle new_chart-icon"
>-</i
>
</div>
</div>
</template>
<script>
import BaseChart from "@/components/charts/BaseChart.vue";
export default {
components: {
BaseChart,
},
data() {
return {
charts: [
{
id: 1,
isShown: true,
},
{
id: 2,
isShown: true,
},
{
id: 3,
isShown: true,
},
{
id: 4,
isShown: true,
},
{
id: 5,
isShown: true,
},
{
id: 6,
isShown: true,
},
],
};
},
methods: {
addChart(id) {
const chart = this.charts.find((chart) => chart.id === id);
if (chart) {
chart.isShown = true;
}
},
removeChart(id) {
const chart = this.charts.find((chart) => chart.id === id);
if (chart) {
chart.isShown = false;
}
},
},
};
</script>
This solution is applicable for a fixed array length. If you plan to create an unlimited number of graphs, then the code will have to be changed.
In this case, we cannot use the index as a key when iterating through v-for. When adding a new element, you need to generate a unique id and add a new element to the array. To delete an element, you just need to filter the current array by the element id.
<template>
<div class="monitor-container">
<div
class="monitor_interface-chart-container"
v-for="chart in charts"
:key="chart.id"
>
<BaseChart />
<i @click="removeChart(chart.id)" class="pi pi-plus-circle new_chart-icon"
>-</i
>
</div>
<i @click="addChart()" class="pi pi-plus-circle new_chart-icon">+</i>
</div>
</template>
<script>
import BaseChart from "@/components/charts/BaseChart.vue";
export default {
components: {
BaseChart,
},
data() {
return {
charts: [],
};
},
methods: {
addChart(id) {
const biggestId = this.charts.reduce(
(acc, rec) => (acc.id > rec.id ? acc.id : rec.id),
0
);
this.charts.push({ id: biggestId + 1 });
},
removeChart(id) {
this.charts = this.charts.filter((chart) => chart.id !== id);
},
},
};
</script>