在加载数据之前触发mounted方法 - VueJS

Posted

技术标签:

【中文标题】在加载数据之前触发mounted方法 - VueJS【英文标题】:mounted method is fired before data loaded - 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。如果我只使用一个生命周期钩子,这将是完全相同的问题。我想使用的内容没有加载。 【参考方案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
   );
 

我希望这有帮助。

【讨论】:

以上是关于在加载数据之前触发mounted方法 - VueJS的主要内容,如果未能解决你的问题,请参考以下文章

mounted钩子函数中请求数据导致页面闪屏问题

Vuejs中关于computedmethodswatch,mounted的区别

Vuejs中关于computedmethodswatch,mounted的区别

使用 Jest 和 Typescript 对 VueJ 进行单元测试 - 未安装组件

js:说说页面加载完之前那些事(loading多函数加载mounted)

vue-router两个不同的路由共用一个component的问题