POST 和 PUT 请求中的问题,使用 axios、vuetify 数据表、vuejs
Posted
技术标签:
【中文标题】POST 和 PUT 请求中的问题,使用 axios、vuetify 数据表、vuejs【英文标题】:Problem in POST and PUT request, with axios, vuetify datatable, vuejs 【发布时间】:2020-08-07 03:03:42 【问题描述】:我正在尝试根据我的需要通过实施 axios 来使用我的 api 来调整 vuetify 网站本身的示例数据表。 GET AND DELETE 方法运行良好,但是我对 POST AND PUT 方法很困惑,我使用 2 个模型作为客户端以及与类型的关系,跟随部分代码:
<template>
<v-data-table
:headers="headers"
:items="clients"
sort-by="firstName"
class="elevation-2"
>
<template v-slot:top>
<v-toolbar flat color="white">
<v-icon medium>mdi-account-supervisor</v-icon>
<v-toolbar-title> Clients</v-toolbar-title>
<v-divider
class="mx-4"
inset
vertical
></v-divider>
<v-spacer></v-spacer>
<v-dialog v-model="dialog" max->
<template v-slot:activator=" on ">
<v-btn
color="blue"
dark class="mt-6 mb-4"
v-on="on"
rounded
><v-icon medium>mdi-plus</v-icon>Add new</v-btn>
</template>
<v-card>
<v-card-title>
<span class="headline"> formTitle </span>
</v-card-title>
<v-card-text>
<v-container>
<v-form>
<v-row>
<v-col cols="12" sm="6" md="12">
<v-text-field v-model="editedItem.firstName" label="First Name"></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="12">
<v-text-field v-model="editedItem.lastName" label="Last Name"></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="12">
<v-text-field v-model="editedItem.email" label="E-Mail"></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="12">
<v-text-field v-model="editedItem.phone" label="Phone"></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="12">
<v-text-field v-model="editedItem.mobilePhone" label="Mobile Phone"></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="12">
<!-- select options-->
<v-select
label='Gender'
v-model='editedItem.gender.name'
:items='genders'
item-value='name'
item-text='name'
>
</v-select>
</v-col>
</v-row>
</v-form>
</v-container>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="error" rounded @click="close">Cancel</v-btn>
<v-btn color="primary" rounded @click="save">Save</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-toolbar>
</template>
<template v-slot:item.action=" item ">
<v-icon
small
color="green"
class="mr-2"
@click="editItem(item)"
>
mdi-pencil
</v-icon>
<v-icon
small
color="red"
@click="deleteItem(item)"
>
mdi-delete
</v-icon>
</template>
<template v-slot:no-data>
<v-btn color="primary" @click="initialize">Reset</v-btn>
</template>
</v-data-table>
</template>
<script>
import axios from 'axios'
import Client from '../../services/clients';
import Gender from '../../services/genders';
export default
data: () => (
dialog: false,
headers: [
text: 'First Name',
align: 'start',
sortable: false,
value: 'firstName',
,
text: 'Last Name', value: 'lastName' ,
text: 'Email', value: 'email' ,
text: 'Phone', value: 'phone' ,
text: 'Mobile Phone', value: 'mobilePhone' ,
text: 'Gender', value: 'gender.name' ,
text: 'Actions', value: 'action', sortable: false ,
],
clients: [],
genders: [],
errors: [],
editedIndex: -1,
editedItem:
firstName: '',
lastName: '',
email: '',
phone: '',
mobilePhone: '',
gender: '',
,
defaultItem:
firstName: '',
lastName: '',
email: '',
phone: '',
mobilePhone: '',
gender: '',
,
),
computed:
formTitle ()
return this.editedIndex === -1 ? 'New Item' : 'Edit Item'
,
,
watch:
dialog (val)
val || this.close()
,
,
created ()
this.initialize()
,
methods:
initialize ()
Client.list().then(response =>
this.clients = response.data
).catch(e =>
console.log(e)
);
Gender.list().then(response =>
this.genders = response.data
).catch(e =>
console.log(e)
);
,
editItem (item)
axios.put('http://192.168.26.130:3000/client/' + item.id)
.then(response =>
this.editedIndex = this.clients.indexOf(item)
this.editedItem = Object.assign(, item)
this.editedID = this.editedItem.id
this.dialog = true
this.response = response
).catch(e =>
console.log(e)
);
,
deleteItem (item)
if (confirm("Do you really want to delete?"))
axios.delete('http://192.168.26.130:3000/client/' + item.id)
.then(response =>
const index = this.clients.indexOf(item)
this.deletedItem = Object.assign(, item)
this.deletedID = this.deletedItem.id
this.clients.splice(index, 1);
this.response = response
).catch(e =>
console.log(e)
);
,
close ()
this.dialog = false
setTimeout(() =>
this.editedItem = Object.assign(, this.defaultItem)
this.editedIndex = -1
, 300)
,
save ()
if (this.editedIndex > -1)
axios.post('http://192.168.26.130:3000/client/')
.then(response =>
Object.assign(this.clients[this.editedIndex], this.editedItem)
this.response = response.data
).catch(e =>
console.log(e)
);
else
this.clients.push(this.editedItem)
this.close()
,
,
</script>
在打开modal添加item时,只有在打开select和修改genre的时候,在保存之前就已经出现了这个错误,如图:
点击保存时只保存在最前面,更新页面时记录消失,谁能给我指点一下?
更新编辑。
经过一些更改,我认为我更接近解决方案,但我遇到了以下障碍,保存客户端项目时,性别存储为空。
的console.log和前端保存的项目但在数据库中性别为空
DataTable.vue 文件:
<template>
<v-data-table
:headers="headers"
:items="clients"
sort-by="firstName"
class="elevation-2"
>
<template v-slot:top>
<v-toolbar flat color="white">
<v-icon medium>mdi-account-supervisor</v-icon>
<v-toolbar-title> Clients</v-toolbar-title>
<v-divider
class="mx-4"
inset
vertical
></v-divider>
<v-spacer></v-spacer>
<v-dialog v-model="dialog" max->
<template v-slot:activator=" on ">
<v-btn
color="blue"
dark class="mt-6 mb-4"
v-on="on"
rounded
><v-icon medium>mdi-plus</v-icon>Add new</v-btn>
</template>
<v-card>
<v-card-title>
<span class="headline"> formTitle </span>
</v-card-title>
<v-card-text>
<v-container>
<v-form>
<v-row>
<v-col cols="12" sm="6" md="12">
<v-text-field v-model="editedItem.firstName" label="First Name"></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="12">
<v-text-field v-model="editedItem.lastName" label="Last Name"></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="12">
<v-text-field v-model="editedItem.email" label="E-Mail"></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="12">
<v-text-field v-model="editedItem.phone" label="Phone"></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="12">
<v-text-field v-model="editedItem.mobilePhone" label="Mobile Phone"></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="12">
<!-- select options-->
<v-select
label='Gender'
v-model='editedItem.gender'
:items='genders'
item-value='name'
item-text='name'
>
</v-select>
</v-col>
</v-row>
</v-form>
</v-container>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="error" rounded @click="close">Cancel</v-btn>
<v-btn color="primary" rounded @click="save">Save</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-toolbar>
</template>
<template v-slot:item.action=" item ">
<v-icon
small
color="green"
class="mr-2"
@click="editItem(item)"
>
mdi-pencil
</v-icon>
<v-icon
small
color="red"
@click="deleteItem(item)"
>
mdi-delete
</v-icon>
</template>
<template v-slot:no-data>
<v-btn color="primary" @click="initialize">Reset</v-btn>
</template>
</v-data-table>
</template>
<script>
import axios from 'axios'
import Client from '../../services/clients';
import Gender from '../../services/genders';
export default
data: () => (
dialog: false,
headers: [
text: 'First Name',
align: 'start',
sortable: false,
value: 'firstName',
,
text: 'Last Name', value: 'lastName' ,
text: 'Email', value: 'email' ,
text: 'Phone', value: 'phone' ,
text: 'Mobile Phone', value: 'mobilePhone' ,
text: 'Gender', value: 'gender.name' ,
text: 'Actions', value: 'action', sortable: false ,
],
clients: [],
genders: [],
errors: [],
editedIndex: -1,
editedItem:
firstName: '',
lastName: '',
email: '',
phone: '',
mobilePhone: '',
gender: '',
,
defaultItem:
firstName: '',
lastName: '',
email: '',
phone: '',
mobilePhone: '',
gender: '',
,
),
computed:
formTitle ()
return this.editedIndex === -1 ? 'New Item' : 'Edit Item'
,
,
watch:
dialog (val)
val || this.close()
,
,
created ()
this.initialize()
,
methods:
initialize ()
Client.list().then(response =>
this.clients = response.data
).catch(e =>
console.log(e)
);
Gender.list().then(response =>
this.genders = response.data
).catch(e =>
console.log(e)
);
,
editItem (item)
axios.put('http://192.168.26.130:3000/client/' + item.id)
.then(response =>
this.editedIndex = this.clients.indexOf(item)
this.editedItem = Object.assign(, item)
this.editedID = this.editedItem.id
this.dialog = true
this.response = response
).catch(error =>
console.log(error.response)
);
,
deleteItem (item)
if (confirm("Do you really want to delete?"))
axios.delete('http://192.168.26.130:3000/client/' + item.id)
.then(response =>
const index = this.clients.indexOf(item)
this.deletedItem = Object.assign(, item)
this.deletedID = this.deletedItem.id
this.clients.splice(index, 1);
this.response = response
).catch(error =>
console.log(error.response)
);
,
close ()
this.dialog = false
setTimeout(() =>
this.editedItem = Object.assign(, this.defaultItem)
this.editedIndex = -1
, 300)
,
save ()
if (this.editedIndex > -1)
Object.assign(this.clients[this.editedIndex], this.editedItem)
else
this.clients.push(this.editedItem)
axios.post('http://192.168.26.130:3000/client/', this.editedItem)
.then(response =>
console.log(response)
).catch(error =>
console.log(error.response)
);
this.close()
,
,
</script>
请有人帮助我吗?
【问题讨论】:
【参考方案1】:有几个问题。首先,您没有将任何数据传递给您的 PUT
和 POST
请求。它们应该看起来像:
editItem (item)
// YOU NEED TO PASS AN OBJECT TO THE PUT REQUEST ▼▼HERE▼▼
axios.put('http://192.168.26.130:3000/client/' + item.id , item)
.then(response =>
// handle response...
)
.catch(err => console.log(error) )
,
save ()
if (this.editedIndex > -1)
// YOU NEED TO PASS AN OBJECT TO THE POST REQUEST ▼▼HERE▼▼
axios.post('http://192.168.26.130:3000/client/', this.editedItem)
.then(response =>
// handle response...
)
.catch(err => console.log(error) )
else /* ... */
,
其次,在底层,<v-select>
使用v-for
来遍历所有应该进入下拉菜单的选项。如果这是一个纯 html <select>
元素,它看起来像这样:
<select name="gender">
<option value="">Select a gender...</option>
<option
v-for="gender in genders"
:key="gender"
value="gender.value"
>
gender.text
</option>
</select>
Vuetify 期望性别数组采用以下两种格式之一:字符串数组或具有text
和value
属性的对象数组:
const genders = ['male', 'female', 'other']
// OR
const genders = [
value: 1, text: 'male' , // `value` can be anything you want
value: 2, text: 'female' ,
value: 3, text: 'other' ,
]
或者,如果您的 genders
数组具有不同的数据结构,您可以告诉 Vuetify 为 value
和 text
属性使用哪些属性(这就是您所做的)。因此,如果您的性别数组如下所示:
const genders = [
name: 'male' ,
name: 'female' ,
name: 'other' ,
]
您的 <v-select>
应该如下所示(在您的情况下,您对文本和值都使用了 SAME 属性,这样做非常好):
<v-select
v-model="editedItem.gender"
:items="genders"
item-text="name"
return-object
/>
根据您附加的图片,我猜测genders
数组不是这些格式之一,当 Vuetify 尝试将其转换为下拉列表时,这会导致错误。另外,我认为您打算将所选值分配给editedItem.gender
而不是editedItem.gender.name
。这里是a codepen showing how to use objects for v-select
items。
如果items
数组是我之前展示的两种格式之一,则不需要指定item-text
和item-value
属性。它们会被自动检测到。
希望这会有所帮助!
【讨论】:
感谢您帮助澄清一些观点:流派矩阵正在从数据库中提取,现在随着更改,在保存此错误 500Error: "Request failed with status code 500" createError createError.js: 16 settle settle.js: 17 handleLoad xhr.js: 61 DataTable.vue: 212
这意味着您创建新用户的 API 请求失败。 500 表示错误在服务器端。我的猜测是您发送到服务器的数据不是服务器期望的格式。您要么需要更改正在发送的数据结构,要么编辑服务器端以便能够接受您正在发送的结构。
我几乎得到了解决方案,现在我已经设法保存在数据库中,除了数据库中仍然为空的类型,信息必须以这种格式到达:@ 987654346@
我相信我在这部分代码中犯了罪:defaultItem: firstName: '', lastName: '', email: '', phone: '', mobilePhone: '', gender: '', ,
会是这个吗?
您是否有理由使用对象来存储性别?为什么不把它变成像名字这样的纯文本属性呢?以上是关于POST 和 PUT 请求中的问题,使用 axios、vuetify 数据表、vuejs的主要内容,如果未能解决你的问题,请参考以下文章
Express 无法接收来自 axios put 请求的正文
Vue.js / Vuex + axios 发送多个 PUT 请求
Vue-cli webpack 设置Axios发起请求统一前缀的路径(设置统一请求地址)(发起GET请求,发起POST请求,发起PUT请求,发起DELETE请求)
API 未在 axios put 中检测 PUT 请求中的模型