首页 > 解决方案 > 如何使用 Vuex 将对象添加到数组中?

问题描述

我正在尝试使用 Vuejs 和 Vuex 制作一个待办事项列表。
我正在使用 Vue CLI。

这是商店:

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

Vue.use(Vuex);

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

这是模块商店:

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,
};


这是在Todo Container中使用App.vue并充当父元素的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>

这是Todo,子元素:

<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>

通过使用 Vue Devtools,我可以看到有对象被推入数组,但它们的idandtitle是未定义的。

我是 Vuejs 和 Vuex 的初学者。即使在阅读 vue 文档时我也无法弄清楚问题:https ://vuex.vuejs.org/guide/actions.html

我在这里发帖是因为我在 6 多个小时内找不到任何关于我的问题的信息。我绝望了。

标签: javascriptvue.js

解决方案


addTask ,deleteTask 的工作示例(可以相应地添加其他功能)。

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

代码 - 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 [容器组件]

<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 [子组件]

<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>

推荐阅读