【问题标题】:Vue - Cannot set property of undefined in promiseVue - 无法在承诺中设置未定义的属性
【发布时间】:2017-09-22 14:41:34
【问题描述】:

所以我有以下 Vue 文件:

<template>

  <li class="notifications new">
      <a href="" data-toggle="dropdown"> <i class="fa fa-bell-o"></i> <sup>
          <span class="counter">0</span>
          </sup>
       </a>
       <div class="dropdown-menu notifications-dropdown-menu animated flipInX">
            <ul v-for="notification in notifications" @click="" class="notifications-container">
              <li>
                <div class="img-col">
                  <div class="img" style="background-image: url('assets/faces/3.jpg')"></div>
                </div>
              </li>
            </ul>
        </div>
  </li>

</template>

<script>
export default {

    data: function() {
        return {
          notifications: [],
          message: "",
        }
    },

    methods: {

        loadData: function() {
            Vue.http.get('/notifications').then(function(response) {

                console.log(response.data);
                //this.notifications = response.data;
                //this.notifications.push(response.data);

                this.message = "This is a message";

                console.log(this.message);
            });

        },
    },

    mounted() {
        this.loadData();
    },

}

</script>

这编译得很好,但是,在加载网页时,我收到以下错误:

app.js:1769 Uncaught (in promise) TypeError: Cannot set property 'message' of undefined

我也尝试过创建另一种方法,但没有任何乐趣。我似乎无法弄清楚为什么在这里无法访问this

【问题讨论】:

  • 不知道怎么用http,因为我用的是axios,不过你可以试试 let that = this; Vue.http.get()..{ that.message = "这是一条消息"; }
  • @GerardoRosciano 嗨,不...仍然得到相同的响应:(
  • 你在使用 Vue 资源吗?
  • 看起来您正在使用 Vue 资源。如果你是,那么除了下面的答案之外,使用this.$http.get 代替Vue.http.get 也应该可以解决问题。

标签: javascript vue.js


【解决方案1】:

你的上下文正在改变:因为你使用了关键字functionthis 在它的作用域内是匿名函数,而不是 vue 实例。

改用箭头函数。

  loadData: function() {
        Vue.http.get('/notifications').then((response) => {

            console.log(response.data);
            //this.notifications = response.data;
            //this.notifications.push(response.data);

            this.message = "This is a message";

            console.log(this.message);
        });

    },

注意:顺便说一句,您应该继续使用关键字 function 作为您的方法的顶级(如示例所示),否则 Vue 不能t 将 vue 实例绑定到this

【讨论】:

  • 谢谢。但是,这似乎只适用于字符串。我有一个数组返回,很好的对象.. response.data 给了我Object, Object, Objectthis.notifications = response.data; console.log(this.notifications) 给了Object {__ob__: Observer} ??
  • 观察者是 VueJS 中的正常事物,它们附加到数据对象中的每个属性,这是 vuejs 跟踪更改并立即更新它们的一种方式 @Phorce 建议使用 Vue Devtools chrome 扩展
  • @BelminBedak 是否有教程或其他东西可以实现我想做的事情?我似乎在这方面找不到任何东西
  • 问题是你想要达到的目标?您确定通知的响应包含任何数据吗?正如建议的 Vue Devtools 会帮助你很多,你可以准确地看到数据模型中的每个属性包含什么。 @Phorce
  • @BelminBedak - 我想基本上调用 API,然后获取数据并将其显示在列表中。 response.data 包含 3 个对象..0: Object { message: "Welcome to the application"} 等..
【解决方案2】:

可以在代码块外将this 设置为const,并使用该常量值访问类属性。

const self = this;

blockMethod(function(data) {
    self.prop = data.val();
})

【讨论】:

  • 对此还有什么解释吗?
【解决方案3】:

还有另一个常见原因,我一直在想为什么您会收到此错误消息。如果你使用 v-if 而不是 v-show 来隐藏一个项目,它不会在 DOM 中,最初不会加载,也不会被引用。我花了一段时间才弄清楚为什么会出现上面的错误消息:

vm.$refs.refpersonview.Person = ...

原因是我有条件地将组件隐藏在 v-if 块中。请改用 v-show!

【讨论】:

    【解决方案4】:

    在promise中使用箭头函数然后你可以访问'this'对象。

    loadData: function() {
            Vue.http.get('/notifications').then(response => {
                console.log(response.data);
                //this.message = 'Something'
            });
    
        }
    

    【讨论】:

      【解决方案5】:
      created() {
      pipedrive.getAllDeals()
      .then(response => {
        // JSON responses are automatically parsed.
        this.posts = response.data
      })
      .catch(e => {
        this.errors.push(e)
      })
      
      // async / await version (created() becomes async created())
      //
      // try {
      //   const response = await axios.get(`http://jsonplaceholder.typicode.com/posts`)
      //   this.posts = response.data
      // } catch (e) {
      //   this.errors.push(e)
      // }
      

      }

      【讨论】:

      • 请详细说明解决方案,以便其他人更容易理解
      • 你可以试试箭头函数
      【解决方案6】:

      我们需要使用 shorthand 属性来定义方法。例如

      export default {
        name: "Posts",
        data() {
          return {
            posts: [],
          };
        },
        methods: {
          async fetchPosts() {
            this.posts = await fetch("http://jsonplaceholder.typicode.com/posts")
                .then(x => x.json())
                .catch(e => console.error(e));
          }
        },
        created() {
          this.fetchPosts();
        }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-03-07
        • 2019-03-10
        • 2020-01-01
        • 2019-05-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多