Vuex

by Huy Tuấn

HTML

<script src="https://unpkg.com/vuex@3.0.1/dist/vuex.min.js"></script>
<script src="https://unpkg.com/vue@2.5.3/dist/vue.min.js"></script>
<div class="container">
            <h1>Todo List</h1>
            <div id="app"></div>
        </div>
        <template id="todo-list">
            <ul class="tasks">
                <li v-for="todo in todos"
                    :class="{completed: todo.completed}"
                    class="task"
                    @click="toggleTodo(todo.id)"
                    @dblclick="deleteTodo(todo.id)">{{todo.task}}</li>
            </ul>
        </template>
        <template id="app-template">
            <div>
                <form @submit.prevent="addTodo">
                    <input class="todo-input" type="text" placeholder="Enter a new Task" v-model="task" />
                </form>
                <todo-list />
            </div>
        </template>

CSS

html {
        font-family: sans-serif;
        background: linear-gradient(45deg, #6cfd9f, #6887ff);
        height: 100%;
        color: #333;
    }
    body {
        display: flex;
        height: 100%;
        margin: 0;
    }
    .container {
        width: 24rem;
        margin: auto;
        background-color: white;
        border-radius: 0.5rem;
        padding: 1rem;
        box-shadow: 0 0 2rem rgba(0, 0, 0, 0.25);
    }
    h1 {
        text-align: center;
        margin-top: 0;
    }
    .todo-input {
        width: 100%;
        padding: 0.5rem;
        font-size: 1rem;
        outline: none;
        border-radius: 0.25rem;
        border-style: none;
        border: solid 1px lightgray;
        box-sizing: border-box;
    }
    .tasks {
        padding-left: 1.5rem;
    }
    .task {
        margin-bottom: 0.5rem;
    }
    .task:hover {
        cursor: pointer;
    }
    .completed {
        text-decoration: line-through;
        color: #555;
    }

Vue

var state = {
    todos: [
        {
            id: 0,
            task: "To Do List 01 ",
            completed: false
        },
        {
            id: 1,
            task: "To Do List 02",
            completed: true
        },
        {
            id: 2,
            task: "To Do List 03",
            completed: false
        }
    ]
};

var getters = {
        getTodos: state => state.todos
};
    
var mutations = {
    ADD_TODO: (state, payload) => {

        var newTask = {
            id: payload.newId,
            task: payload.task,
            completed: false
        }

        state.todos.unshift(newTask);
    },
    TOGGLE_TODO: (state, payload) => {
        var item = state.todos.find(todo => todo.id === payload);
        item.completed = !item.completed;
    },
    DELETE_TODO: (state, payload) => {
        var index = state.todos.findIndex(todo => todo.id === payload);
        state.todos.splice(index, 1);
    }
};

var actions = {
    addTodo: (context, payload) => {
        context.commit("ADD_TODO", payload)
    },
    toggleTodo: (context, payload) => {
        context.commit("TOGGLE_TODO", payload)
    },
    deleteTodo: (context, payload) => {
        context.commit("DELETE_TODO", payload)
    }
}

var store = new Vuex.Store({
    state: state,
    getters: getters,
    mutations: mutations,
    actions: actions
});


Vue.component("todo-list", {
    computed: {
        todos() {
            return this.$store.getters.getTodos;
        }
    },
    methods: {
        toggleTodo: function(id) {
            this.$store.dispatch("toggleTodo", id);
        },
        deleteTodo: function(id) {
            this.$store.dispatch("deleteTodo", id);
        }
    },
    template: "#todo-list"
});
    

 var app = new Vue({
    data: () => ({
        task: "",
        newId: 3
    }),
    methods: {
        addTodo: function() {
            this.$store.dispatch("addTodo", this);
            this.newId ++;
            this.task = "";
        }
   ...