nuxt中的fetch和asyncData是两个比较重要的概念,今天看看这两个方法使用以及他们的区别。

    fetch

    假设我们现在的代码是这样:

    1. <script>
    2.     export default {
    3.         async fetch() {
    4.             this.name = await new Promise((resolve, reject) => {
    5.     console.log('fetch start');
    6.     setTimeout(() => {
    7.         console.log('fetch end');
    8.         resolve(Math.random().toString(36).substr(2));
    9.     }, 1000)
    10.             })
    11.         },
    12.         beforeCreate() {
    13.             console.log('beforeCreate');
    14.         },
    15.         created() {
    16.             console.log('created');
    17.         },
    18.         beforeMount() {
    19.             console.log('beforeMount')
    20.         },
    21.         mounted() {
    22.             console.log('mounted');
    23.         }
    24.     }
    25. </script>

    执行时机问题

    在服务端运行的时候,fetch是发生在created之后:

    如果发生在客户端(例如页面跳转会触发fetch),那么fetch发生在beforeMounted之后:

    上面例子中的fetch执行了1s,因此执行完,可能到mounted之后了。

    fetch的一些相关变量

    我们先看下面的代码:

    1. <p v-if="$fetchState.pending">Fetching mountains...</p>
    2. <p v-else-if="$fetchState.error">An error occurred :(</p>
    3. <div v-else>
    4.     <div>{{name}}</div>
    5.     <button @click="$fetch">Refresh</button>
    6. </div>

    上面的 $fetchState就是记录fetch中的一些状态信息,其中panding表示fetch进行中,error表示fetch失败了。

    button点击的时候,可以调用$fetch,重新触发fetch,看图如下:

    需要注意的是,fetch方法里面不能传参数,可以通过this.$nuxt.context获取context.

    fetch相关参数

    fetchOnServer:true/false,默认true,表示fetch是否发生在服务端,上面的例子中,fetch发生在服务端的created之后,我们看看设置成false如何,这个是在页面级上进行设置:

    1. export default {
    2.   data() {
    3.     return {
    4.       posts: []
    5.     }
    6.   },
    7.   async fetch() {
    8.     this.posts = await fetch('https://api.nuxtjs.dev/posts').then(res =>
    9.       res.json()
    10.     )
    11.   },
    12.   // call fetch only on client-side
    13.   fetchOnServer: false;
    14. }

    看看效果:

    可以看到服务端没有执行fetch了,只是在客户端执行fetch。

    fetchDelay:Number(默认200),fetch最少执行的时间,防止因为fetch执行太快,导致一闪而过。

    监听页面参数调用fetch

    1. export default {
    2.   watch: {
    3.     '$route.query': '$fetch'
    4.   },
    5.   async fetch() {
    6.     // Called also on query changes
    7.   }}

    $fetchState.timestamp

    当我们使用nuxt中的缓存组件(加keep-alive),例如:

    1. <template>
    2.   <nuxt keep-alive />
    3. </template>

    我们可以在activated中,配合$fetchState.timestamp来更新fetch,其中的$fetchState.timestamp是fetch的最后执行时间:

    1. export default {
    2.     data() {
    3.       return {
    4.         posts: []
    5.       }
    6.     },
    7.     activated() {
    8.       // Call fetch again if last fetch more than 30 sec ago
    9.       if (this.$fetchState.timestamp <= Date.now() - 30000) {
    10.         this.$fetch()
    11.       }
    12.     },
    13.     async fetch() {
    14.       this.posts = await fetch('https://api.nuxtjs.dev/posts').then(res =>
    15.         res.json()
    16.       )
    17.     }
    18. }

    asyncData

    asyncData只是在页面(page目录下)可以使用,组件(components目录下)不可以使用。

    假设我们代码如下:

    1. export default {
    2.     async asyncData(context) {
    3.         console.log('asyncData start');
    4.         let name = await new Promise((resolve, reject) => {
    5.             resolve('ok');
    6.             console.log('asyncData end');
    7.         });
    8.         return {
    9.             name
    10.         }
    11.     },
    12.     beforeCreate() {
    13.         console.log('beforeCreate');
    14.     },
    15.     created() {
    16.         console.log('created');
    17.     },
    18.     beforeMount() {
    19.         console.log('beforeMount')
    20.     },
    21.     mounted() {
    22.         console.log('mounted');
    23.     },
    24. }

    执行阶段

    asyncData是发生在路由(route)阶段,我们先看服务端:

    发生在beforeCreate之前,我们在看看客户端(发生跳转时,会执行asyncData):

    在客户端,也是发生在beforeCreate之前。

    两者不同

    执行时机不同

    fetch发生在created之后,fetch可以通过$fetchState获取fetch的状态。

    asyncData发生在路由阶段(route),asyncData没有获取状态的方法。

    发生错误不一样

    asyncData发生在路由阶段,如果执行过程中发生了错误,那么就会进入错误页面,整个页面打不开。

    fetch发生在页面渲染之前,此时页面已经打开了,如果发生了错误,那么$fetchData.error为true,页面还是存在的。

    范围不同

    fetch在页面(page目录下)和组件(components目录下)都可以执行;

    asyncData只是在页面(page目录下)才执行。

    参数不同

    fetch方法不能传参数,需要通过this.$nuxt.context获取context。

    asyncData方法可以接受context参数。

    意义不同

    fetch可以操作页面上data中的对象。

    asyncData返回的结果将和页面上data进行合并,再渲染页面。

    回到顶部
    我要评论

    所有评论

      相关文章