(Vue) Axios 设置数据不适用于 2 个属性。我无法解释为什么
(Vue) Axios set data not working with 2 properties. I can't explain why
我遇到了我遇到过的最奇怪的错误。我在我的 Vue 项目中使用 Axios 和 Vee-Validate,但在我的 api 中出现错误。所以有了 axios 我有一个收获。
示例:
this.$http.post('v1/auth/register', {
first_name: this.first_name,
last_name: this.last_name,
email: this.email,
phone: this.phone,
password:this.password
}).then((response) => {
this.registration_card = 2;
}).catch((error) => {
if(error.data.error.message === "email_already_exists") {
let input = this.$refs['email'].$children[0];
input.errors.add({ field: 'email', msg: 'email already is use'});
this.loading = false;
console.log(input.errors);
console.log(this.loading);
}
});
奇怪的部分来了。使用此代码:
let input = this.$refs['email'].$children[0];
input.errors.add({ field: 'email', msg: 'email already is use'});
this.loading = false;
input.errors仍然是空的,不会显示错误。但是当我这样做时:
let input = this.$refs['email'].$children[0];
input.errors.add({ field: 'email', msg: 'email already is use'});
// this.loading = false;
所以 this.loading 不会被设置,然后错误会被设置并显示在我的视图中。
但我希望 this.loading 仍然是 false,因为我不希望显示我的加载图标。任何人对此都有解释。
编辑:更多代码
methods: {
register: function () {
let anyError = false;
this.$validate(this, ['first_name', 'last_name', 'phone', 'email', 'password'], function (value, last_item) {
this.loading = true;
if (value === false) {
anyError = true;
}
if (anyError || !last_item) {
return;
}
this.$http.post('v1/auth/register', {
first_name: this.first_name,
last_name: this.last_name,
email: this.email,
phone: this.phone,
password: this.password
}).then((response) => {
this.registration_card = 2;
}).catch((error) => {
if (error.data.error.message === "email_already_exists") {
let input = this.$refs['email'].$children[0];
input.errors.add({field: 'email', msg: 'email already is use'});
this.loadingTest = false;
console.log(input.errors);
console.log(this.loadingTest);
}
});
}.bind(this));
},
}
this.$validate 这样做:
export default function(scope, arrayOfValues, callback) {
let total = arrayOfValues.length - 1;
let last_item = false;
arrayOfValues.forEach(function(value, index) {
let input = scope.$refs[value].$children[0];
input.$validator.validate().then(value => callback(value, total === index, index));
});
}
我这样做是因为我有自定义输入组件
编辑:这是我使用加载的地方:
<j-button label="Register" :loading="loading" @click.native="register"/>
按钮组件是:
<template>
<button type="button">
<span v-if="!loading">{{label}}</span>
<loading v-if="loading"/>
</button>
</template>
<script>
import loading from 'vue-loading-spinner/src/components/Circle'
export default {
name: 'j-button',
props: [
'label',
'loading'
],
components: {
loading
}
}
</script>
编辑:更多代码!!!!!!
我的 j 输入组件
<template>
<div>
<label v-bind:class="{ 'active': (newValue.length > 0)}">{{label}}</label>
<input v-bind:class="{ 'error': (errors.has(name))}" type="text" :name="name" v-validate="rules" :placeholder="label" v-model="newValue" v-on:input="updateValue()" ref="input">
<span v-if="errors.has(name)">{{errors.first(name)}}</span>
</div>
</template>
<script>
export default {
name: 'j-text',
inject: ['$validator'],
props: [
'label',
'name',
'rules',
'value',
],
data() {
return {
newValue: ''
}
},
created() {
this.newValue = this.value;
this.updateValue();
},
methods: {
updateValue: function () {
this.$emit('input', this.newValue);
},
}
}
</script>
这个很简单。仅引用更改刷新 Vue 视图。
当你这样做时:
new Vue({
data: ['property'],
method: {
change() {
this.property = "yes"; // will get refreshed
}
}
});
视图得到刷新(显示更改)。但是当您更改对象的字段引用(而不是对象本身)或在其上调用方法时,它 不会刷新 .
change() {
this.property.field = "yes"; // won't get refreshed
this.property.mtehod("yes"); // won't get refreshed
}
Vue.js 仅对某些特定方法(如 array.push()
)进行了调整,以识别这些方法会刷新视图。如果你想让它工作,你需要调用 this.$forceUpdate()
或使用 Vue.set()
来改变值。
因此当您添加错误时,视图不会刷新,只有当您更改数据时 属性 (loading
) 视图会识别数据值已更改并刷新您的视图。
请阅读Reactivity in Depth,尤其是第"How Changes Are Tracked"章。请查看哪些设置数据的方式是被动的,哪些不是。
所以我找到了问题,但仍然很奇怪为什么。我会为此提出另一个问题。关于我的 j 按钮组件:
<template>
<button type="button">
<span v-if="!loading">{{label}}</span>
<loading v-if="loading"/>
</button>
</template>
<script>
import loading from 'vue-loading-spinner/src/components/Circle'
export default {
name: 'jellow-button',
props: [
'label',
'loading'
],
components: {
loading
}
}
</script>
为了解决这个奇怪的问题,我不得不改变这个:
<loading v-if="loading"/>
收件人:
<loading v-show="loading"/>
如果我改变了这个,那么将加载错误并且按钮加载图标将被关闭,在我的捕获中执行此操作:
}).catch(error => {
if(error.data.error.message === "email_already_exists") {
let input = this.$refs['email'].$children[0];
input.errors.add({field: 'email', msg: 'email already in use'});
this.loading = false;
}
});
但又一次。如果我在按钮中执行 v-if 而不是 v-show,则不会显示错误。很奇怪。我将创建另一个问题,希望我能得到答案。
我遇到了我遇到过的最奇怪的错误。我在我的 Vue 项目中使用 Axios 和 Vee-Validate,但在我的 api 中出现错误。所以有了 axios 我有一个收获。
示例:
this.$http.post('v1/auth/register', {
first_name: this.first_name,
last_name: this.last_name,
email: this.email,
phone: this.phone,
password:this.password
}).then((response) => {
this.registration_card = 2;
}).catch((error) => {
if(error.data.error.message === "email_already_exists") {
let input = this.$refs['email'].$children[0];
input.errors.add({ field: 'email', msg: 'email already is use'});
this.loading = false;
console.log(input.errors);
console.log(this.loading);
}
});
奇怪的部分来了。使用此代码:
let input = this.$refs['email'].$children[0];
input.errors.add({ field: 'email', msg: 'email already is use'});
this.loading = false;
input.errors仍然是空的,不会显示错误。但是当我这样做时:
let input = this.$refs['email'].$children[0];
input.errors.add({ field: 'email', msg: 'email already is use'});
// this.loading = false;
所以 this.loading 不会被设置,然后错误会被设置并显示在我的视图中。
但我希望 this.loading 仍然是 false,因为我不希望显示我的加载图标。任何人对此都有解释。
编辑:更多代码
methods: {
register: function () {
let anyError = false;
this.$validate(this, ['first_name', 'last_name', 'phone', 'email', 'password'], function (value, last_item) {
this.loading = true;
if (value === false) {
anyError = true;
}
if (anyError || !last_item) {
return;
}
this.$http.post('v1/auth/register', {
first_name: this.first_name,
last_name: this.last_name,
email: this.email,
phone: this.phone,
password: this.password
}).then((response) => {
this.registration_card = 2;
}).catch((error) => {
if (error.data.error.message === "email_already_exists") {
let input = this.$refs['email'].$children[0];
input.errors.add({field: 'email', msg: 'email already is use'});
this.loadingTest = false;
console.log(input.errors);
console.log(this.loadingTest);
}
});
}.bind(this));
},
}
this.$validate 这样做:
export default function(scope, arrayOfValues, callback) {
let total = arrayOfValues.length - 1;
let last_item = false;
arrayOfValues.forEach(function(value, index) {
let input = scope.$refs[value].$children[0];
input.$validator.validate().then(value => callback(value, total === index, index));
});
}
我这样做是因为我有自定义输入组件
编辑:这是我使用加载的地方:
<j-button label="Register" :loading="loading" @click.native="register"/>
按钮组件是:
<template>
<button type="button">
<span v-if="!loading">{{label}}</span>
<loading v-if="loading"/>
</button>
</template>
<script>
import loading from 'vue-loading-spinner/src/components/Circle'
export default {
name: 'j-button',
props: [
'label',
'loading'
],
components: {
loading
}
}
</script>
编辑:更多代码!!!!!!
我的 j 输入组件
<template>
<div>
<label v-bind:class="{ 'active': (newValue.length > 0)}">{{label}}</label>
<input v-bind:class="{ 'error': (errors.has(name))}" type="text" :name="name" v-validate="rules" :placeholder="label" v-model="newValue" v-on:input="updateValue()" ref="input">
<span v-if="errors.has(name)">{{errors.first(name)}}</span>
</div>
</template>
<script>
export default {
name: 'j-text',
inject: ['$validator'],
props: [
'label',
'name',
'rules',
'value',
],
data() {
return {
newValue: ''
}
},
created() {
this.newValue = this.value;
this.updateValue();
},
methods: {
updateValue: function () {
this.$emit('input', this.newValue);
},
}
}
</script>
这个很简单。仅引用更改刷新 Vue 视图。
当你这样做时:
new Vue({
data: ['property'],
method: {
change() {
this.property = "yes"; // will get refreshed
}
}
});
视图得到刷新(显示更改)。但是当您更改对象的字段引用(而不是对象本身)或在其上调用方法时,它 不会刷新 .
change() {
this.property.field = "yes"; // won't get refreshed
this.property.mtehod("yes"); // won't get refreshed
}
Vue.js 仅对某些特定方法(如 array.push()
)进行了调整,以识别这些方法会刷新视图。如果你想让它工作,你需要调用 this.$forceUpdate()
或使用 Vue.set()
来改变值。
因此当您添加错误时,视图不会刷新,只有当您更改数据时 属性 (loading
) 视图会识别数据值已更改并刷新您的视图。
请阅读Reactivity in Depth,尤其是第"How Changes Are Tracked"章。请查看哪些设置数据的方式是被动的,哪些不是。
所以我找到了问题,但仍然很奇怪为什么。我会为此提出另一个问题。关于我的 j 按钮组件:
<template>
<button type="button">
<span v-if="!loading">{{label}}</span>
<loading v-if="loading"/>
</button>
</template>
<script>
import loading from 'vue-loading-spinner/src/components/Circle'
export default {
name: 'jellow-button',
props: [
'label',
'loading'
],
components: {
loading
}
}
</script>
为了解决这个奇怪的问题,我不得不改变这个:
<loading v-if="loading"/>
收件人:
<loading v-show="loading"/>
如果我改变了这个,那么将加载错误并且按钮加载图标将被关闭,在我的捕获中执行此操作:
}).catch(error => {
if(error.data.error.message === "email_already_exists") {
let input = this.$refs['email'].$children[0];
input.errors.add({field: 'email', msg: 'email already in use'});
this.loading = false;
}
});
但又一次。如果我在按钮中执行 v-if 而不是 v-show,则不会显示错误。很奇怪。我将创建另一个问题,希望我能得到答案。