1

I am trying to make a Todo List using Vuejs and Vuex.
I am using Vue CLI.

This is the store:

import Vue from 'vue';
import Vuex from 'vuex';
import todoList from "./modules/todoList"

Vue.use(Vuex);

export default new Vuex.Store({
    modules: {
        todoList
    }
})

This is the module store:

const state = {
  todoList: [
    {
      id: 1,
      title: "Todo One",
    },
    {
      id: 2,
      title: "Todo Two",
    },
  ],
};

const getters = {
  getTodoList: (state) => state.todoList,
};

const actions = {
  addTask({ commit }, task) {
    commit("ADD_TASK", task);
    task.title = "";
  },
};
const mutations = {
  ADD_TASK(state, task) {
    state.todoList.push({
        id: task.id,
        title: task.title
    });

  },
};

export default {
  state,
  getters,
  actions,
  mutations,
};


This is the Todo Container that is used in App.vue and acts as a parent element for Todo :

<template>
  <section>
    <h2>Todo List</h2>
    <input type="checkbox" v-model="showDoneTasks" name="" id="" />
    <Todo />
    <div>
      <input
        type="text"
        name="enterTodo"
        placeholder="What are you up today ?"
        v-model="task.title"
      />
      <button @click="addTask">
        <i class="fas fa-plus"></i>
      </button>
    </div>
  </section>
</template>

<script>
import Todo from "./Todo.vue";
import { mapActions } from "vuex";

export default {
  name: "TodoContainer",
  components: {
    Todo,
  },
  data: () => {
    return {
      task: {
        id: 0,
        title: ""
      },
      checkBox: false,
    };
  },
  methods: {
    ...mapActions({
      addTask: 'addTask',
    }),
    removeTask() {},
    editTask() {},
    completeTask() {},
    showDoneTasks() {
      this.checkBox = !this.checkBox;
    },
  },
  computed: {},
};
</script>

<style scoped></style>

This is Todo, the child element:

<template>
  <div>
    <div class="todo" v-for="todo in getTodoList" :key="todo.id">
      {{ todo.title }}
    </div>
  </div>
</template>

<script>
import { mapGetters } from "vuex";

export default {
  name: "Todo",
  computed: {
    ...mapGetters(["getTodoList"]),
  },
};
</script>

<style scoped></style>

By using the Vue Devtools I can see that there are objected being pushed into the array, but their id and title is undefined.

I am a total beginner in Vuejs and Vuex. I can't figure out the problem even while reading the vue documenation: https://vuex.vuejs.org/guide/actions.html

I have posted here because I couldn't find anything regarding my problem in over 6 hours. I am hopeless.

2
  • 2
    <button @click="addTask"> is addTask(event) <- not a task, make @click="addTask(task)" Commented Jun 10, 2020 at 20:35
  • How did this work ? Commented Jun 10, 2020 at 20:43

1 Answer 1

1

Working example for addTask ,deleteTask(other functions can be added accordingly).

https://vuex-todos-jorje.netlify.app/

code- https://github.com/manojkmishra/vuex_todos_jorje

store.js

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

export default new Vuex.Store({
state: {todoList: [  ],  },
getters: { getTodoList: (state) => state.todoList,  },
mutations: {
ADD_TASK(state, title) {
  if (state.todoList.map(todoList => todoList.title).indexOf(title) === -1)    
 { state.todoList.push({ title})
  }
},
DELETE_TASK(state, title) {
state.todoList.splice(state.todoList.indexOf(title), 1)
},
},
actions: {
addTask({ commit }, task) {  
  commit("ADD_TASK", task.title);
},
deleteTask({ commit }, title) {
   commit("DELETE_TASK", title)
},
},
 modules: {  }
})

Todos.vue [container component]

<template>
<div class="App">
<div class="App__box">
  <Todo v-for="(todo, index) in todos"
    :key="index" :text="todo.title" @delete="deleteTask(todo)"
  ></Todo>
</div>
<div>
  <input  class="inp" type="text" name="enterTodo" 
    placeholder="What are  you up today ?"
    v-model="task.title"/>
  <button @click="addTask">Add </button>
</div>
</div>
</template>
<script>
import Todo from './Todo'
import { mapActions } from 'vuex'
export default {
name: 'App',
components: {Todo },
data () {  return { task: {  id: '', title: ''  }, }  },
computed: {
  todos () { console.log('store',this.$store.state)
     return this.$store.state.todoList},
},
methods: {
  ...mapActions([ 'deleteTask',]),
  addTask (e) { if (this.task) { this.$store.dispatch('addTask', this.task);
  this.task.title='' }  },
}
}
</script>
<style scoped>
i{padding:5px}
.App__box{
 padding-bottom:30px;
}
</style>

Todo.js [child component]

<template>
<div class="todo" >
 {{ text }}
 <button  @click="$emit('delete')" >del</button>
</div>
</template>
<script>
import { mapGetters } from "vuex";
export default {
name: "Todo",
props: {  text: { type: String, default: '',  },  },
};
</script>
<style scoped>
.todo{
padding-top:10px;
padding-bottom:10px;
}
</style>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.