Vue.js:如何将特定对象中的布尔字段从 false 更改为 true @click 处于突变状态和带有动作 axios 的服务器?
Posted
技术标签:
【中文标题】Vue.js:如何将特定对象中的布尔字段从 false 更改为 true @click 处于突变状态和带有动作 axios 的服务器?【英文标题】:Vue.js: How to change booleanfield in specific object from false to true @click in state with mutations and server with actions axios? 【发布时间】:2020-07-26 02:32:41 【问题描述】:当我执行 @click="updateTodoItem(todo.id, todo.title, todo.body) 时,我想将一个对象 (todo) 的布尔值从 false 更改为 true
这就是 1 个对象的外观:id: 1, title: "", body: "", done: false
更新(已完成): 我想通了并在这里更新了代码。我只能将 done 一个参数作为有效负载传递给存储操作。
首页.vue
<template>
<div class="container">
<section class="hero is-link">
<div class="hero-body">
<div class="container">
<h1 class="title">
Hello Dudes
</h1>
<h2 class="subtitle">
Hamster ToDo List
</h2>
</div>
</div>
</section>
<section class="section">
<nav class="level">
<div class="level-item has-text-centered">
<div>
<p class="heading">All Tasks</p>
<p class="title">getTotalTodos</p>
</div>
</div>
<div class="level-item has-text-centered">
<div>
<p class="heading">Tasks has to be done</p>
<p class="title">getTodosFalse</p>
</div>
</div>
<div class="level-item has-text-centered">
<div>
<p class="heading">Tasks finished</p>
<p class="title">getTodosTrue</p>
</div>
</div>
<!-- <div class="level-item has-text-centered">
<div>
<p class="heading">Likes</p>
<p class="title">789</p>
</div>
</div> -->
</nav>
</section>
<section class="section">
<div class="columns">
<div class="column is-half">
<strong>Add ToDo</strong>
<div class="control">
<input class="input is-info" v-model="todoTitle" type="text" placeholder="Add Task Title">
<input class="input is-info" v-model="todoBody" type="text" placeholder="Add Task Body">
<button class="button is-link" @click="addTodoItem(title: todoTitle, body: todoBody, done: false); empyInput()">Add</button>
</div>
</div>
</div>
<div class="tabs is-small">
<ul>
<li class="is-active"><a>All Tasks </a></li> <span class="tag is-link">getTotalTodos</span>
<li><a>Tasks still not done</a></li><span class="tag is-link">getTodosFalse</span>
<li><a>Finished Tasks</a></li><span class="tag is-link">getTodosTrue</span>
<!-- <li><a>Documents</a></li> -->
</ul>
</div>
<article class="media" v-for="todo in todoItems" :key="todo.id">
<figure class="media-left">
<!-- <p class="image is-64x64">
<img src="https://bulma.io/images/placeholders/128x128.png">
</p> -->
</figure>
<div class="media-content">
<div class="content">
<p>
<strong>todo.title</strong>
<br>
todo.body
</p>
</div>
<nav class="level is-mobile">
<div class="level-left">
<a class="level-item">
<span class="icon is-small"><i class="fas fa-edit"></i></span>
</a>
<a class="level-item" v-if="todo.done==false" @click="updateTodoToTrue(todo.id)">
<span class="icon is-small"><i class="fas fa-check"></i></span>
</a>
<a class="level-item" v-if="todo.done==true" @click="updateTodoToFalse(todo.id)">
<span class="icon is-small"><i class="fas fa-undo"></i></span>
</a>
<a class="level-item" @click="deleteTodoItem(todo.id)">
<span class="icon is-small"><i class="fas fa-trash"></i></span>
</a>
</div>
</nav>
</div>
<div class="media-right">
<button class="delete" @click="deleteTodoItem(todo.id)"></button>
</div>
</article>
</section>
</div>
</template>
<script>
// @ is an alias to /src
import mapGetters from 'vuex';
import mapActions from 'vuex';
export default
name: 'Home',
data()
return
todoTitle: '',
todoBody: '',
,
// updated()
// this.$store.dispatch('getTodoItems');
// ,
computed:
...mapGetters(['todoItems', 'getTotalTodos', 'getTodosTrue', 'getTodosFalse'])
,
methods:
...mapActions(['addTodoItem', 'deleteTodoItem', 'updateTodoToTrue', 'updateTodoToFalse']),
// addTodo()
// return this.$store.actions.addTodoItem;
empyInput()
this.todoTitle = '';
this.todoBody = '';
</script>
商店
import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios';
Vue.use(Vuex)
export default new Vuex.Store(
state:
todoItems: []
,
// Keep in mind that response is an HTTP response
// returned by the Promise.
// The mutations are in charge of updating the client state.
mutations:
UPDATE_TODO_ITEMS (state, payload)
state.todoItems = payload;
,
ADD_TODO_ITEMS (state, payload)
state.todoItems.push(payload)
,
DELETE_TODO_ITEMS (state, payload)
state.todoItems.splice(payload, 1)
,
changeTodoStatus: (state, payload) =>
let index = state.todoItems.findIndex(el =>
return el.id == payload.id
)
state.todoItems[index].done = payload.done
,
actions:
getTodoItems ( commit )
axios.get('http://127.0.0.1:8000/api/').then((response) =>
commit('UPDATE_TODO_ITEMS', response.data)
);
,
addTodoItem ( commit , todoItem)
axios.post('http://127.0.0.1:8000/api/', todoItem).then((response) =>
commit('ADD_TODO_ITEMS', response.data)
);
,
deleteTodoItem ( commit , todoItemId)
axios.delete('http://127.0.0.1:8000/api/' + todoItemId + '/').then((response) =>
commit('DELETE_TODO_ITEMS', response.data)
);
,
updateTodoToTrue ( commit , todoItemId)
var payload =
done: true
;
axios.patch('http://127.0.0.1:8000/api/' + todoItemId + '/', payload).then((response) =>
commit('changeTodoStatus', response.data)
);
,
updateTodoToFalse ( commit , todoItemId)
var payload =
done: false
;
axios.patch('http://127.0.0.1:8000/api/' + todoItemId + '/', payload).then((response) =>
commit('changeTodoStatus', response.data)
);
,
,
getters:
todoItems: state => state.todoItems,
getTotalTodos: state => state.todoItems.length,
getTodosTrue: state => state.todoItems.filter(todo => todo.done).length,
getTodosFalse: state => state.todoItems.filter(todo => !todo.done).length
,
modules:
)
【问题讨论】:
【参考方案1】:我的问题是我试图将 3 个参数传递给商店中的操作有效负载。该操作仅接受 1 个参数,即有效负载。我将 axios 方法从 PUT 更改为 PATCH。
主页.vue
<template>
<div class="container">
<section class="hero is-link">
<div class="hero-body">
<div class="container">
<h1 class="title">
Hello Dudes
</h1>
<h2 class="subtitle">
Hamster ToDo List
</h2>
</div>
</div>
</section>
<section class="section">
<nav class="level">
<div class="level-item has-text-centered">
<div>
<p class="heading">All Tasks</p>
<p class="title">getTotalTodos</p>
</div>
</div>
<div class="level-item has-text-centered">
<div>
<p class="heading">Tasks has to be done</p>
<p class="title">getTodosFalse</p>
</div>
</div>
<div class="level-item has-text-centered">
<div>
<p class="heading">Tasks finished</p>
<p class="title">getTodosTrue</p>
</div>
</div>
<!-- <div class="level-item has-text-centered">
<div>
<p class="heading">Likes</p>
<p class="title">789</p>
</div>
</div> -->
</nav>
</section>
<section class="section">
<div class="columns">
<div class="column is-half">
<strong>Add ToDo</strong>
<div class="control">
<input class="input is-info" v-model="todoTitle" type="text" placeholder="Add Task Title">
<input class="input is-info" v-model="todoBody" type="text" placeholder="Add Task Body">
<button class="button is-link" @click="addTodoItem(title: todoTitle, body: todoBody, done: false); empyInput()">Add</button>
</div>
</div>
</div>
<div class="tabs is-small">
<ul>
<li class="is-active"><a>All Tasks </a></li> <span class="tag is-link">getTotalTodos</span>
<li><a>Tasks still not done</a></li><span class="tag is-link">getTodosFalse</span>
<li><a>Finished Tasks</a></li><span class="tag is-link">getTodosTrue</span>
<!-- <li><a>Documents</a></li> -->
</ul>
</div>
<article class="media" v-for="todo in todoItems" :key="todo.id">
<figure class="media-left">
<!-- <p class="image is-64x64">
<img src="https://bulma.io/images/placeholders/128x128.png">
</p> -->
</figure>
<div class="media-content">
<div class="content">
<p>
<strong>todo.title</strong>
<br>
todo.body
</p>
</div>
<nav class="level is-mobile">
<div class="level-left">
<a class="level-item">
<span class="icon is-small"><i class="fas fa-edit"></i></span>
</a>
<a class="level-item" v-if="todo.done==false" @click="updateTodoToTrue(todo.id)">
<span class="icon is-small"><i class="fas fa-check"></i></span>
</a>
<a class="level-item" v-if="todo.done==true" @click="updateTodoToFalse(todo.id)">
<span class="icon is-small"><i class="fas fa-undo"></i></span>
</a>
<a class="level-item" @click="deleteTodoItem(todo.id)">
<span class="icon is-small"><i class="fas fa-trash"></i></span>
</a>
</div>
</nav>
</div>
<div class="media-right">
<button class="delete" @click="deleteTodoItem(todo.id)"></button>
</div>
</article>
</section>
</div>
</template>
<script>
// @ is an alias to /src
import mapGetters from 'vuex';
import mapActions from 'vuex';
export default
name: 'Home',
data()
return
todoTitle: '',
todoBody: '',
,
// updated()
// this.$store.dispatch('getTodoItems');
// ,
computed:
...mapGetters(['todoItems', 'getTotalTodos', 'getTodosTrue', 'getTodosFalse'])
,
methods:
...mapActions(['addTodoItem', 'deleteTodoItem', 'updateTodoToTrue', 'updateTodoToFalse']),
// addTodo()
// return this.$store.actions.addTodoItem;
empyInput()
this.todoTitle = '';
this.todoBody = '';
</script>
商店
import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios';
Vue.use(Vuex)
export default new Vuex.Store(
state:
todoItems: []
,
// Keep in mind that response is an HTTP response
// returned by the Promise.
// The mutations are in charge of updating the client state.
mutations:
UPDATE_TODO_ITEMS (state, payload)
state.todoItems = payload;
,
ADD_TODO_ITEMS (state, payload)
state.todoItems.push(payload)
,
DELETE_TODO_ITEMS (state, payload)
state.todoItems.splice(payload, 1)
,
changeTodoStatus: (state, payload) =>
let index = state.todoItems.findIndex(el =>
return el.id == payload.id
)
state.todoItems[index].done = payload.done
,
actions:
getTodoItems ( commit )
axios.get('http://127.0.0.1:8000/api/').then((response) =>
commit('UPDATE_TODO_ITEMS', response.data)
);
,
addTodoItem ( commit , todoItem)
axios.post('http://127.0.0.1:8000/api/', todoItem).then((response) =>
commit('ADD_TODO_ITEMS', response.data)
);
,
deleteTodoItem ( commit , todoItemId)
axios.delete('http://127.0.0.1:8000/api/' + todoItemId + '/').then((response) =>
commit('DELETE_TODO_ITEMS', response.data)
);
,
updateTodoToTrue ( commit , todoItemId)
var payload =
done: true
;
axios.patch('http://127.0.0.1:8000/api/' + todoItemId + '/', payload).then((response) =>
commit('changeTodoStatus', response.data)
);
,
updateTodoToFalse ( commit , todoItemId)
var payload =
done: false
;
axios.patch('http://127.0.0.1:8000/api/' + todoItemId + '/', payload).then((response) =>
commit('changeTodoStatus', response.data)
);
,
,
getters:
todoItems: state => state.todoItems,
getTotalTodos: state => state.todoItems.length,
getTodosTrue: state => state.todoItems.filter(todo => todo.done).length,
getTodosFalse: state => state.todoItems.filter(todo => !todo.done).length
,
modules:
)
【讨论】:
以上是关于Vue.js:如何将特定对象中的布尔字段从 false 更改为 true @click 处于突变状态和带有动作 axios 的服务器?的主要内容,如果未能解决你的问题,请参考以下文章
如何从对象数组中获取特定数据并存储在js(vue js)中的新数组中
Vue.js - 如何按特定属性对数组中的对象进行排序并使用“v-for”进行渲染