【问题标题】:mounted method is fired before data loaded - VueJS在加载数据之前触发mounted方法 - VueJS
【发布时间】:2018-05-22 21:07:04
【问题描述】:

我正在使用Vue Resource 从 REST API 检索图像集合。请求在我的 Vue 组件的 created 钩子中发送。

问题是,我正在尝试访问 mounted 挂钩中检索到的数据,但未加载数据。

我在控制台中收到此错误:

[Vue 警告]:挂载钩子错误:“TypeError:无法读取未定义的属性 'forEach'”

这是我的组件:

<script>
export default {
  data() {
    return { imgs : '' };
  },
  created() {
    // the full url is declare in my main.js
    this.imgs = this.$resource('acf/v3/pages/4');

    this.imgs.query().then((response) => {
      console.log('success', response);
      this.imgs = response.data.acf.gallery;
    }, (response) => {
      console.log('erreur', response);
    });
  },
  mounted() {
    // get the ref="image" in my dom template
    let imgs = this.$refs.image;

    imgs.forEach((img) => {
      // I do some stuff with imgs
    });
  }
}
</script>

如果我将setTimeout 包裹在mounted 的内容周围,一切正常。

所以,我不明白如何在执行 mounted 挂钩之前等待我的数据加载。这不就是 Vue 生命周期钩子的作用吗?

【问题讨论】:

  • 为什么不直接使用 created()?
  • 因为created 中没有任何反应。在 mounted 钩子之前你不能操作 DOM。 check this documentation。如果我只使用一个生命周期钩子,这将是完全相同的问题。我想使用的内容没有加载。

标签: vue.js lifecycle vue-resource


【解决方案1】:

由于this.imgs.query() 调用是异步的,因此您的mounted 钩子在then 处理程序设置this.imgs 之前被调用(我假设它与v-for 绑定到模板中的元素带有属性ref="image")。因此,即使组件已经挂载到 DOM,$refs 还没有设置。

我会创建一个“使用 imgs 做一些事情”的方法,然后在异步调用的 then 处理程序中的 $nextTick callback 中调用该方法。传递给 $nextTick 的回调将“在下一个 DOM 更新周期后执行”,这意味着此时将设置 $refs

<script>
export default {
  data() {
    return { imgs: '' };
  },
  created() {
    // the full url is declare in my main.js
    this.imgs = this.$resource('acf/v3/pages/4');

    this.imgs.query().then((response) => {
      console.log('success', response);
      this.imgs = response.data.acf.gallery;
      this.$nextTick(() => this.doStuffWithImgs());
    }, (response) => {
      console.log('erreur', response);
    });
  },
  methods: {
    doStuffWithImgs() {
      // get the ref="image" in my dom template
      let imgs = this.$refs.image;

      imgs.forEach((img) => {
        // I do some stuff with imgs
      });
    }
  }
}
</script>

【讨论】:

  • 我不知道$nextTick。谢谢,它正在按预期工作。
  • @thanksd 这就是它通常的做法,因为我猜所有 vuejs 应用程序都以某种方式或其他方式使用来自某个 api 的数据,然后基于它创建 dom。我想知道它通常是如何完成的
  • @anekix 有很多方法可以处理 Vue 应用程序中的一般异步行为。如果您需要在组件挂载之前影响this.$refs 数组中的数据,那么是的,使用$nextTick 是最好和最常用的方法。
【解决方案2】:

如Vue实例的Lifecycle Diagram所示。在 Mounted Hook(这意味着我们可以访问 DOM)之后,还有 beforeUpdateupdated 钩子。这些钩子可以在数据更改时使用。我认为beforeUpdateupdate钩子可以在created hook中获取数据后使用。

<script>
   export default {
      data() {
         return { imgs : '' };
       },
   created() {
    // the full url is declare in my main.js
    this.imgs = this.$resource('acf/v3/pages/4');

    this.imgs.query().then((response) => {
        console.log('success', response);
        this.imgs = response.data.acf.gallery;
       }, (response) => {
         console.log('erreur', response);
     });
   },
  // here we can use beforeUpdate or updated hook instead of mounted
  beforeUpdate() {
    // get the ref="image" in my dom template
    let imgs = this.$refs.image;

    imgs.forEach((img) => {
    // I do some stuff with imgs
   });
 }
}
我希望这有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-07
    • 2011-06-13
    • 2017-12-09
    • 2016-05-06
    • 2018-07-17
    • 2021-06-15
    • 2014-08-27
    相关资源
    最近更新 更多