Components

We will need two components for our TODO app:

  • TodoItem - actual task item in the list of tasks.
  • TodoCreate - section at the bottom of the list for creating new items.

At first we need to create folder todo for our components at Application\src\components. In this folder create files: TodoItem.vue and TodoCreate.vue.

Item Component

Put this code to TodoItem.vue:

<template>
    <div class="TodoItem">
        <!--DONE-->
        <BaseNavigationButton @click="click($event.target)"
                              :icon="'icon-ok'"
                              :class-name="'TodoItem__done'"
                              v-if="!done" />

        <!--TITLE-->
        <div class="TodoItem__title" :class="{'TodoItem__title_done':done}">{{title}}</div>

    </div>
</template>

<script>
    import BaseNavigationButton from '../common/BaseNavigationButton.vue';

    export default {
        name: 'TodoItem',
        components: {
            BaseNavigationButton
        },
        props: {
            //Title
            title: {
                type: String,
                required: true
            },
            //Done
            done: {
                type: Boolean,
                required: true
            }
        },
        methods: {
            click: function (e) {
                this.$emit('markAsDone', e);
            }
        }
    };
</script>

<style>
    .TodoItem {
        overflow: hidden;
        display: flex;
        flex-direction: row;
        align-items: center;
        padding: 16px;
    }

    .TodoItem__done {
        color: #546E7A;
        font-size: 20px;
        margin-right: 8px;
    }

    .TodoItem__title {
        flex: 1 1 auto;
        font-size: 20px;
    }

    .TodoItem__title_done {
        text-decoration: line-through;
        margin-left: 36px;
    }
</style>

Create Component

Put this code to TodoCreate.vue:

<template>
    <div class="TodoCreate">
        <!--CREATE-->
        <BaseNavigationButton @click="createItem()"
                              :icon="'icon-plus'"
                              :class-name="'TodoCreate__create'" />

        <!--TITLE-->
        <BaseText :label="'TODO__WHAT_NEEDS_TO_BE_DONE'"
                  :class-name="'TodoCreate__title'"
                  :errors="errors['title']"
                  :value="title"
                  @change="setTitle($event.target.value)"
                  @enter="createItem()" />

    </div>
</template>

<script>
    import { mapActions, mapState } from 'vuex';
    import BaseNavigationButton from '../common/BaseNavigationButton.vue';
    import BaseText from '../common/BaseText.vue';

    export default {
        name: 'TodoCreate',
        components: {
            BaseNavigationButton,
            BaseText
        },
        computed: {
            ...mapState({
                title: s => s.todo.title,
                errors: s => s.todo.errors
            })
        },
        methods: {
            ...mapActions({
                setTitle: 'todo/setTitle',
                createItem: 'todo/createItem'
            })
        }
    };
</script>

<style>
    .TodoCreate {
        overflow: hidden;
        display: flex;
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
        padding: 16px;
    }

    .TodoCreate__create {
        color: #546E7A;
        font-size: 20px;
        margin-right: 8px;
    }

    .BaseText__container.TodoCreate__title {
        flex: 1 1 auto;
        margin: 0;
    }

    .TodoCreate__title .BaseText__input {
        border-bottom: none;
        padding: 6px 8px 8px 5px;
    }

    .TodoCreate__title .BaseText__label {
        top: 6px;
    }

    .TodoCreate__title .BaseText__input:focus ~ .BaseText__label {
        display: none;
    }

    .TodoCreate__title .BaseText__input:valid ~ .BaseText__label {
        display: none;
    }

    .TodoCreate__title .BaseErrors {
        display: none;
    }
</style>