Vuex 动作改变组件数据
Vuex action changes component data
我有以下组件,它只是一个简单的登录表单:
<template>
<v-card>
<v-card-title primary-title class="headline white--text primary">Login</v-card-title>
<form @keyup.enter="submit( form )" @submit.prevent="submit( form )">
<v-card-text>
<v-text-field
label="Email address"
required
:error-messages="errors['email']"
v-model="form.email"
/>
<v-text-field
label="Password"
hint="At least 8 characters"
minlength="8"
:append-icon="passwordVisible ? 'visibility_off' : 'visibility'"
:append-icon-cb="() => (passwordVisible = !passwordVisible)"
:type="passwordVisible ? 'text' : 'password'"
required
counter
:error-messages="errors['password']"
v-model="form.password"
/>
</v-card-text>
<v-card-actions>
<v-btn type="submit" color="primary">Login</v-btn>
</v-card-actions>
</form>
</v-card>
</template>
<script>
export default
{
metaInfo: {
title: 'Login'
},
data()
{
return {
form: {
email: '',
password: '',
},
passwordVisible: false,
}
},
computed: {
errors()
{
return this.$store.getters.errors;
}
},
methods: {
submit( data )
{
this.$store.dispatch( 'userLogin', data );
}
},
}
</script>
userLogin
操作看起来像:
userLogin( context, data )
{
// Base64 encode password
data.password = btoa( data.password );
fetch( '/api/users/login', {
headers: {
'X-Requested-With': 'XMLHttpRequest',
'X-CSRF-token': window.token,
'Content-Type': 'application/json',
'Accept': 'application/json'
},
method: 'POST',
body: JSON.stringify( data )
})
.then( response => {
return response.json();
})
.then( response => {
// If there are any errors
if( response.errors )
{
context.commit( 'errors', response.errors );
}
context.commit( 'message', response.message );
context.commit( 'success', response.success ? response.success : false );
if( response.token )
{
context.commit( 'userLogin', response.token );
}
})
.catch( error => {
console.error( 'userLogin', error );
});
}
在我尝试登录之前,表单中的所有内容都按预期工作。提交表单后,操作会运行 2 次。第一次我得到了预期的结果,它是由 API 生成的标记。然而,第二次模板中的密码字段已更改为 base64 值。
所以我的问题是为什么这个动作执行了两次?为什么密码字段的值在组件内只有 "stored and read" 时会发生变化?
希望有人能帮我解决问题。
为什么动作执行了两次
您在表单上附加了两个事件侦听器:
@submit.prevent
@keyup.enter
这两个事件的事件处理程序是 submit( form )
,它正在调度操作
当您专注于输入字段并点击回车按钮时,表单将被提交 implicitly。
因此 submit( form )
将被调用两次 ;
- 正在调用表单的提交方法
- 由于按下回车按钮,
@keyup.enter
的事件处理程序也被调用
为什么密码字段的值在组件内只有 "stored and read" 时会发生变化?
您正在将 form
作为负载传递给作为对象的操作:
form: { email: '', password: '', }
在 JavaScript 个对象是 passed by reference.
在您的操作中,您将 form
对象的密码 属性 突变为
data.password = btoa( data.password );
因此更改也反映在组件中
---------------------------------
解决方案
why is the action executed twice
由于输入框处于焦点时按回车键的默认行为是提交表单,因此您可以删除 @keyup.enter
侦听器
Why does the password field value change when the value is only "stored and read" from within the component?
不改变原始对象。而是创建一个新的并将其作为您的 post 请求主体
传递
// Base64 encode password
let details = {
email: data.email,
password: btoa( data.password )
}
fetch( '/api/users/login', {
headers: {
'X-Requested-With': 'XMLHttpRequest',
'X-CSRF-token': window.token,
'Content-Type': 'application/json',
'Accept': 'application/json'
},
method: 'POST',
body: JSON.stringify( details )
})
我有以下组件,它只是一个简单的登录表单:
<template>
<v-card>
<v-card-title primary-title class="headline white--text primary">Login</v-card-title>
<form @keyup.enter="submit( form )" @submit.prevent="submit( form )">
<v-card-text>
<v-text-field
label="Email address"
required
:error-messages="errors['email']"
v-model="form.email"
/>
<v-text-field
label="Password"
hint="At least 8 characters"
minlength="8"
:append-icon="passwordVisible ? 'visibility_off' : 'visibility'"
:append-icon-cb="() => (passwordVisible = !passwordVisible)"
:type="passwordVisible ? 'text' : 'password'"
required
counter
:error-messages="errors['password']"
v-model="form.password"
/>
</v-card-text>
<v-card-actions>
<v-btn type="submit" color="primary">Login</v-btn>
</v-card-actions>
</form>
</v-card>
</template>
<script>
export default
{
metaInfo: {
title: 'Login'
},
data()
{
return {
form: {
email: '',
password: '',
},
passwordVisible: false,
}
},
computed: {
errors()
{
return this.$store.getters.errors;
}
},
methods: {
submit( data )
{
this.$store.dispatch( 'userLogin', data );
}
},
}
</script>
userLogin
操作看起来像:
userLogin( context, data )
{
// Base64 encode password
data.password = btoa( data.password );
fetch( '/api/users/login', {
headers: {
'X-Requested-With': 'XMLHttpRequest',
'X-CSRF-token': window.token,
'Content-Type': 'application/json',
'Accept': 'application/json'
},
method: 'POST',
body: JSON.stringify( data )
})
.then( response => {
return response.json();
})
.then( response => {
// If there are any errors
if( response.errors )
{
context.commit( 'errors', response.errors );
}
context.commit( 'message', response.message );
context.commit( 'success', response.success ? response.success : false );
if( response.token )
{
context.commit( 'userLogin', response.token );
}
})
.catch( error => {
console.error( 'userLogin', error );
});
}
在我尝试登录之前,表单中的所有内容都按预期工作。提交表单后,操作会运行 2 次。第一次我得到了预期的结果,它是由 API 生成的标记。然而,第二次模板中的密码字段已更改为 base64 值。
所以我的问题是为什么这个动作执行了两次?为什么密码字段的值在组件内只有 "stored and read" 时会发生变化?
希望有人能帮我解决问题。
为什么动作执行了两次
您在表单上附加了两个事件侦听器:
@submit.prevent
@keyup.enter
这两个事件的事件处理程序是 submit( form )
,它正在调度操作
当您专注于输入字段并点击回车按钮时,表单将被提交 implicitly。
因此 submit( form )
将被调用两次 ;
- 正在调用表单的提交方法
- 由于按下回车按钮,
@keyup.enter
的事件处理程序也被调用
为什么密码字段的值在组件内只有 "stored and read" 时会发生变化?
您正在将 form
作为负载传递给作为对象的操作:
form: { email: '', password: '', }
在 JavaScript 个对象是 passed by reference.
在您的操作中,您将 form
对象的密码 属性 突变为
data.password = btoa( data.password );
因此更改也反映在组件中
---------------------------------
解决方案
why is the action executed twice
由于输入框处于焦点时按回车键的默认行为是提交表单,因此您可以删除 @keyup.enter
侦听器
Why does the password field value change when the value is only "stored and read" from within the component?
不改变原始对象。而是创建一个新的并将其作为您的 post 请求主体
传递// Base64 encode password
let details = {
email: data.email,
password: btoa( data.password )
}
fetch( '/api/users/login', {
headers: {
'X-Requested-With': 'XMLHttpRequest',
'X-CSRF-token': window.token,
'Content-Type': 'application/json',
'Accept': 'application/json'
},
method: 'POST',
body: JSON.stringify( details )
})