<h1>Task Manager</h1>
<div id="app">
<div class="column status__1">
<p class="tag tag1">
まだ
<span>{{ tasksOpen.length }}</span>
</p>
<transition-group name="fade">
<task-card :task="task" v-for="task in tasksOpen" :key="task.name"></task-card>
</transition-group>
</div>
<div class="column status__2">
<p class="tag tag2">
やってる
<span>{{ tasksDoing.length }}</span>
</p>
<transition-group name="fade">
<task-card :task="task" v-for="task in tasksDoing" :key="task.name"></task-card>
</transition-group>
</div>
<div class="column status__3">
<p class="tag tag3">
おわり
<span>{{ tasksClosed.length }}</span>
</p>
<transition-group name="fade">
<task-card :task="task" v-for="task in tasksClosed" :key="task.name"></task-card>
</transition-group>
</div>
<div class="newTaskArea">
<input type="text" v-model="newTaskName" placeholder="やること">
<select v-model="newTaskAsignee">
<option disabled>やらせる人を選択</option>
<option value="🐶">🐶</option>
<option value="🐱">🐱</option>
<option value="🐵">🐵</option>
<option value="🐧">🐧</option>
</select>
<input type="number" v-model="newTaskMandays" placeholder="人/日">
<button @click="addTask">新規追加</button>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
$fa: "Font Awesome 5 Free"
*, *::before, *::after
padding: 0
margin: 0
box-sizing: border-box
body
background: whitesmoke
color: #333
padding: 10px
h1
text-align: center
margin-bottom: 1em
#app
display: flex
flex-wrap: wrap
width: 100%
max-width: 900px
margin: 0 auto
.status
&__1
border-top: 5px solid lightpink
&__2
border-top: 5px solid lightskyblue
&__3
border-top: 5px solid lightseagreen
.column
width: 300px
padding: 10px
margin: 0 auto
background: white
p.tag
font-size: 15px
line-height: 20px
text-align: center
margin-bottom: 30px
&::before
font-family: $fa
font-weight: 900
margin-right: .5em
&1::before
content: '\f024'
color: lightpink
&2::before
content: '\f303'
color: lightskyblue
&3::before
content: '\f00c'
color: lightseagreen
& > span
display: inline-block
width: 20px
min-width: 20px
line-height: 20px
background: #ccc
border-radius: 50%
color: white
text-align: center
vertical-align: middle
margin-left: 1em
.card
width: 100%
padding: 10px
overflow: hidden
position: relative
border-radius: 3px
box-shadow: 0 0 3px rgba(0,0,0,.2)
margin-bottom: 10px
p
padding: 15px
&__bg
position: absolute
font-size: 3em
top: -20px
left: -10px
opacity: .2
&__footer
display: flex
justify-content: space-between
span
color: #ccc
transition: all .2s
&:hover
color: #333
.fade-enter-active, .fade-leave-active
transition: opacity .7s
.fade-enter, .fade-leave-to
opacity: 0
.newTaskArea
margin-top: 15px
padding: 20px 10px
background: white
width: 100%
display: flex
flex-wrap: wrap
justify-content: space-between
input, select, button
min-width: 180px
margin: 10px 20px
padding: 5px
border-radius: 3px
button
flex-grow: 2
View Compiled
Vue.component('task-card', {
props: ['task'],
template: '<div class="card"><p>{{ task.name }}</p><div class="card__bg">{{ task.asignee }}</div><div class="card__footer"><span @click="decStatus(task)"><i class="fas fa-chevron-circle-left"></i></span><span>{{ task.mandays }}人/日</span><span @click="incStatus(task)"><i class="fas fa-chevron-circle-right"></i></span></div></div>',
methods: {
incStatus(task){
if(1 <= task.status && task.status <= 2){
task.status ++
}
},
decStatus(task){
if(2 <= task.status && task.status <= 3){
task.status --
}
}
}
})
let filters = {
open: function(tasks){
return tasks.filter(function(task){
return task.status === 1
})
},
doing: function(tasks){
return tasks.filter(function(task){
return task.status === 2
})
},
closed: function(tasks){
return tasks.filter(function(task){
return task.status === 3
})
}
}
let vm = new Vue({
el: '#app',
data: {
tasks: [
{ name: 'task1', status : 1, asignee: '🐶', mandays : 3 },
{ name: 'task2', status : 2, asignee: '🐱', mandays : 3 },
{ name: 'task3', status : 1, asignee: '🐵', mandays : 1 },
{ name: 'task4', status : 3, asignee: '🐧', mandays : 2 }
],
newTaskName: '',
newTaskAsignee: null,
newTaskMandays: 0
},
computed: {
tasksOpen: function(){
return filters.open(this.tasks)
},
tasksDoing: function(){
return filters.doing(this.tasks)
},
tasksClosed: function(){
return filters.closed(this.tasks)
}
},
methods: {
addTask(){
this.tasks.push({ name: this.newTaskName, status: 1, asignee: this.newTaskAsignee, mandays: this.newTaskMandays })
}
}
})
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.