I have a todosModule which contains the necessary state. The todos array contains the objects. When I output them through the loop, I need the completed property of a specific object in the loop to change when the checkbox changes.
Completed property is boolean.
Down below is file todosModule.js for store (vuex)
import axios from "axios";
export const todosModule = {
state: () => ({
todos: [],
page: 1,
limit: 10,
totalPages: 0,
isTodosLoading: false
}),
getters: {
},
mutations: {
setTodos(state, todos) {
state.todos = todos
},
setPage(state, page) {
state.page = page
},
setTotalPages(state, totalPages) {
state.totalPages = totalPages
},
setLoadingTodos(state, bool) {
state.isTodosLoading = bool
},
setCompleted(state, completed) {
console.log(state.todos.completed)
state.todos.completed = completed
}
},
actions: {
async fetchTodos({state, commit}) {
try {
commit('setLoadingTodos' , true)
const response = await axios.get('https://jsonplaceholder.typicode.com/todos', {
params: {
_page: state.page,
_limit: state.limit
}
})
commit('setTotalPages', Math.ceil(response.headers['x-total-count'] / state.limit))
commit('setTodos', response.data)
}
catch (e) {
console.log(e)
}
finally {
commit('setLoadingTodos', false)
}
}
},
namespaced: true
}
Down below is TodoItem.vue
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<template>
<div >
<div >
<div :>
<div >
<h5 >{{todo.title}}</h5>
<div >
<input type="checkbox" id="flexSwitchCheckChecked" @change="setCompleted" :checked="todo.completed">
</div>
</div>
<p v-if="todo.completed === true" >Выполнено</p>
<p v-else >Невыполнено</p>
<div >
<div >
<button-bootstrap css->Изменить</button-bootstrap>
<button-bootstrap css->Удалить</button-bootstrap>
</div>
<div >
<span >id {{todo.id}}</span>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import ButtonBootstrap from "@/components/UI/ButtonBootstrap";
export default {
name: "TodoItem",
components: {ButtonBootstrap},
props: {
todo: {
type: Object,
required: true
}
},
methods: {
setCompleted(event) {
this.$store.commit('todos/setCompleted', event.target.checked)
},
}
}
</script>
<style lang="scss" scoped>
.form-switch .form-check-input {
margin-left: 0;
}
.btn-list {
button:first-child {
margin-right: 1rem;
}
}
</style>
Parent file TodoList.vue
<template>
<div >
<TodoItem v-for="todo in todos" :todo="todo" :key="todo.id"/>
</div>
</template>
<script>
import TodoItem from "@/components/TodoItem";
export default {
name: "TodoList",
components: {TodoItem},
props: {
todos: {
type: Array,
required: true,
}
}
}
</script>
<style lang="scss" scoped>
.row {
margin-top: 2rem;
}
</style>
Help please, how to change a specific property of a specific object?
UPDATE! I fount a solution!
setCompleted(state, completed) {
const index = state.todos.findIndex(todo => todo.id === completed.id);
state.todos[index].completed = completed.completed
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<template>
<div >
<div >
<div :>
<div >
<h5 >{{todo.title}}</h5>
<div >
<input type="checkbox" id="flexSwitchCheckChecked" @change="setCompleted($event, todo.id)" :checked="todo.completed">
</div>
</div>
<p v-if="todo.completed === true" >Выполнено</p>
<p v-else >Невыполнено</p>
<div >
<div >
<button-bootstrap css->Изменить</button-bootstrap>
<button-bootstrap css->Удалить</button-bootstrap>
</div>
<div >
<span >id {{todo.id}}</span>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import ButtonBootstrap from "@/components/UI/ButtonBootstrap";
export default {
name: "TodoItem",
components: {ButtonBootstrap},
props: {
todo: {
type: Object,
required: true
}
},
methods: {
setCompleted(event, id) {
this.$store.commit('todos/setCompleted', {completed: event.target.checked , id: id});
},
}
}
</script>
<style lang="scss" scoped>
.form-switch .form-check-input {
margin-left: 0;
}
.btn-list {
button:first-child {
margin-right: 1rem;
}
}
</style>
CodePudding user response:
All you have to do is pass an additional attribute to the method
<input type="checkbox" id="flexSwitchCheckChecked" @change="setCompleted($event, todo.id)" :checked="todo.completed">
and then in the setCompleted
handler do the below change
setCompleted(event, id) {
this.$store.commit('todos/setCompleted', {completed: event.target.checked , id: id})
},
and in your todoModules.js file do the below change in the setCompleted
mutation
setCompleted(state, payload) {
const index = state.todos.findIndex(todo => todo.id === payload.id);
state.todos[index].completed = payload.completed;
}