Reputation: 568
I am new on Vue and trying to remove data repetition from my array objects.
VIEW
<div id="app">
<h2>Programming Classes Time</h2>
<div v-for="todo in todos">
<p>{{todo.time}}</p>
/** Is there a way to display 7:00 PM only once and under 7:00 PM display Javascript, JQuery and PHP **/
/** display 8:00 PM only once and under it there should be CSS, HTML and MySQL **/
<p>{{todo.text}}</p>
<br/>
</div>
</div>
SCRIPT
new Vue({
el: "#app",
data: {
todos: [
{ text: "Javascript", time: "7:00 PM" },
{ text: "JQuery", time: "7:00 PM" },
{ text: "PHP", time: "7:00 PM" },
{ text: "CSS", time: "8:00 PM" },
{ text: "HTML", time: "8:00 PM" },
{ text: "MySQL", time: "8:00 PM" }
]
},
methods: {
toggle: function(todo){
todo.done = !todo.done
}
}
})
Is there a way to display 7:00 PM only once and under it display Javascript, JQuery and PHP as an image below?
Below is my code on jsfiddle
https://jsfiddle.net/ujjumaki/hu9ytvwn/14/
Upvotes: 2
Views: 148
Reputation: 2761
you can try:
new Vue({
el: "#app",
data: {
todos: [
{ text: "Javascript", time: "7:00 PM" },
{ text: "Java", time: "8:00 PM" },
{ text: "JQuery", time: "7:00 PM" },
{ text: "PHP", time: "7:00 PM" },
{ text: "CSS", time: "8:00 PM" },
{ text: "HTML", time: "8:00 PM" },
{ text: "Python", time: "7:00 PM" },
{ text: "MySQL", time: "8:00 PM" },
],
resolvedTodos: {}
},
mounted() {
this.resolvedTodos = this.todos.reduce((acc, item) => {
acc[item.time] =
!Object.keys(acc).find(a => a === item.time)
? [item.text]
: [...acc[item.time], item.text]
return acc
}, {})
},
methods: {
toggle: function (todo) {
todo.done = !todo.done;
},
},
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script>
<div id="app">
<h2>Programming Classes Time</h2>
<div v-for="(langs, time in resolvedTodos">
{{ time }}
<div v-for="lang in langs">
{{ lang }}
</div>
<br />
</div>
</div>
Upvotes: 1
Reputation: 164734
Create a computed property to group your data. For example
computed: {
todosByTime () {
const grouped = this.todos.reduce((map, { text, time }) => {
let group = map.get(time) || map.set(time, []).get(time)
group.push(text)
return map
}, new Map())
return Array.from(grouped, ([ time, texts ]) => ({ time, texts }))
}
}
Now you can use this in your template
<dl>
<template v-for="todo in todosByTime" :key="todo.time">
<dt>{{ todo.time }}</dt>
<dd v-for="text in todo.texts">{{ text }}</dd>
</template>
</dl>
Upvotes: 2