在 VueJS 中使用 Axios - 这个未定义
Posted
技术标签:
【中文标题】在 VueJS 中使用 Axios - 这个未定义【英文标题】:Using Axios in VueJS - this undefined 【发布时间】:2019-05-08 12:30:57 【问题描述】:使用 typescript 和 vuejs + axios,我在 post 请求上有以下 .catch 函数 - 我试图捕获一些网络错误并向最终用户报告状态:
.catch(function(error)
console.error(error.response);
if ( error.message === "Network Error" )
this.alert.show = 1;
this.alert.message = error.message + ': Please try again later';
);
this.alert.show 在调试器中抛出未定义的“this”。这是 javascript/typescript 和一般异常处理程序的问题,还是 Axios 中的错误或我找不到文档的设计决策?
在没有“this”引用的情况下,我有没有办法将它传达给我的组件?
完整块:
export default
data()
return
form:
email: '',
password: '',
,
alert:
show: 0,
message: '',
,
;
,
methods:
onSubmit(evt)
evt.preventDefault();
if (this.form.password.length > 0)
// TODO: Hideous workaround for .catch().
let that = this;
this.$http.post('http://localhost:3000/login',
email: this.form.email,
password: this.form.password,
)
.then((response) =>
const is_admin = response.data.user.is_admin;
localStorage.setItem('user', JSON.stringify(response.data.user));
localStorage.setItem('jwt', response.data.token);
if (localStorage.getItem('jwt') != null)
this.$emit('loggedIn');
if (this.$route.params.nextUrl != null)
this.$router.push(this.$route.params.nextUrl);
else
if (is_admin === 1)
this.$router.push('admin');
else
this.$router.push('dashboard');
)
.catch((error) =>
console.error(error);
if ( error.message === 'Network Error' )
this.alert.show = 10;
this.alert.message = error.message + ': Please try again later';
);
,
onReset(evt)
evt.preventDefault();
/* Reset our form values */
this.form.email = '';
this.form.password = '';
/* Trick to reset/clear native browser form validation state */
this.show = false;
this.$nextTick(() => this.show = true; );
,
,
;
Vue 模板(Login.vue):
<template>
<div>
<b-container class="loginPage">
<b-row>
<b-col sm="4"/>
<b-col sm="4">
<b-form @submit="onSubmit" @reset="onReset">
<h2>Login</h2>
<p>Please enter your email and password</p>
<b-form-input id="exampleInput1"
type="email"
v-model="form.email"
required
placeholder="Enter email">
</b-form-input>
<b-form-input id="exampleInput2"
type="password"
v-model="form.password"
required
placeholder="Enter password">
</b-form-input>
</b-form-group>
<div class="forgot">
<a href="reset.html">Forgot password?</a>
</div>
<b-button class="btn-primary" type="submit" variant="primary">Submit</b-button>
<b-button class="btn-reset" type="reset" variant="danger">Reset</b-button>
<b-alert :show="alert.show" variant="danger">
alert.message
</b-alert>
</b-form>
</b-col>
<b-col sm="4"/>
</b-row>
</b-container >
</div>
</template>
也使用https://bootstrap-vue.js.org。
【问题讨论】:
【参考方案1】:您也可以将this
分配给一个全局变量并在回调中访问它:
let that =this;
...
.catch((error) =>
console.error(error.response);
if ( error.message === "Network Error" )
that.alert.show = 1;
that.alert.message = error.message + ': Please try again later';
);
【讨论】:
将this
存储在变量中是否有任何副作用?它会正常收集垃圾吗?
当你的应用程序/组件被销毁时,变量(引用)也会被销毁,它不是一个副本,它只是一个引用,blog.penjee.com/wp-content/uploads/2015/02/…【参考方案2】:
您正在创建一个新的本地函数作用域。请改用粗箭头。
.catch((error) =>
console.error(error.response);
if ( error.message === "Network Error" )
this.alert.show = 1;
this.alert.message = error.message + ': Please try again later';
);
【讨论】:
有趣。 error.response 变得未定义,但调试器仍然显示这是未定义的,但我的登录警告框最终还是出现了。许多基本的 javascript 对我来说仍然是新的,即使使用了多年。 你能展示更多这个块吗?如何调用更大的函数?范围可能会以几种方式丢失。 你的解决方案是最好的,我认为他在其他地方丢失了上下文 我相信你是对的,这是最好的解决方案。它似乎在浏览器(铬)中工作,但调试器仍然显示它是未定义的。添加整个块。似乎只工作一次。 你是如何在 Vue 的上下文中使用它的?以上是关于在 VueJS 中使用 Axios - 这个未定义的主要内容,如果未能解决你的问题,请参考以下文章