【问题标题】:Using Axios in VueJS - this undefined在 VueJS 中使用 Axios - 这个未定义
【发布时间】: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

【问题讨论】:

    标签: javascript typescript vue.js vuejs2 axios


    【解决方案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 的上下文中使用它的?
    猜你喜欢
    • 2020-07-03
    • 1970-01-01
    • 2021-10-10
    • 2021-04-20
    • 1970-01-01
    • 1970-01-01
    • 2017-09-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多