te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>javascript - VueRouter: How do I correctly fetch data before rendering page content? - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - VueRouter: How do I correctly fetch data before rendering page content? - Stack Overflow

programmeradmin4浏览0评论

I'm using Nuxt with Vue Router and Axios. I see Vue Router has this fantastic feature called Navigation Guards.

Unfortunately, in the example below, my beforeRouteEnter() function is called but seems to exit and switch pages before my manual next() method is called in fetchPageData(next).

What is the correct pattern here?

export default {
    beforeRouteEnter (to, from, next) {
        next(vm => {
            vm.fetchPageData(next);
        });
    },
    methods: {
        async fetchPageData(next) {
            const result = await this.$axios.$get('/api/v2/inventory/3906?apiKey=f54761e0-673e-4baf-86c1-0b85a6c8c118');
            this.$storemit('property/setProperty', result[0]);
            next();
        }
    }
}

I assume that my first call to next(vm => {}) is running asynchronously, allowing execution to continue, resulting in a page change before I (most likely incorrectly) try to callback next().

I'm using Nuxt with Vue Router and Axios. I see Vue Router has this fantastic feature called Navigation Guards.

Unfortunately, in the example below, my beforeRouteEnter() function is called but seems to exit and switch pages before my manual next() method is called in fetchPageData(next).

What is the correct pattern here?

export default {
    beforeRouteEnter (to, from, next) {
        next(vm => {
            vm.fetchPageData(next);
        });
    },
    methods: {
        async fetchPageData(next) {
            const result = await this.$axios.$get('/api/v2/inventory/3906?apiKey=f54761e0-673e-4baf-86c1-0b85a6c8c118');
            this.$store.mit('property/setProperty', result[0]);
            next();
        }
    }
}

I assume that my first call to next(vm => {}) is running asynchronously, allowing execution to continue, resulting in a page change before I (most likely incorrectly) try to callback next().

Share Improve this question asked Feb 14, 2020 at 12:34 sparkyspidersparkyspider 13.5k11 gold badges96 silver badges135 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 6

What is happening there, is that you already calling next and that's why the route enters immediately.

Where you are calling next ?

beforeRouteEnter (to, from, next) {
    next(vm => {  // <= HERE you execute next
        vm.fetchPageData(next);
    });
},

And the above code will execute vm.fetchPageData when the ponent is already rendered.

So even if you don't call next on the fetchPageData the route will enter.


By assuming that you want to enter the view after certain data is fetched by BE you can use beforeEnter on the router config:

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      ponent: Foo,
      beforeEnter: (to, from, next) => {
        axios.get('api/...')
          .then(response => {
             store.mit('mutation', response)
             next()
          })
          .catch(e => {
            alert('Something went wrong')
            next(false)
          })
      }
    }
  ]
})

Another solution would be to allow the route to enter but show a loader while data is being fetched: Checkout this answer

You are right, calling next() second time is incorrect. Your first call to next() tells Router "go on, you can proceed with changing active ponent (create/mount/render) and when the ponent is created, call my callback (passed as an argument to next())

You can follow guidance in Data fetching - fetching before navigation Docs ie. fetching data first and call next() after but that requires to extract fetch logic from the ponent itself.

Generally I find easier to write all ponent in the way assuming data are not here on 1st render and are ing later when all async calls resolve...

UPDATE Nuxt async data fetching options

As you are using Nuxt.js you have some other options how to use async data:

  1. nuxtServerInit - useful to fill client-side Vuex store with data from server side
  2. fetch method - The fetch method is used to fill the store before rendering the page. It's like the asyncData method except it doesn't set the ponent data and allows you to put the data into the store. Returning Promise from fetch method will make Nuxt wait for promise to resolve before it renders the ponent...
  3. asyncData method can be used to to fetch data and put it inside ponent's data. Returning Promise from asyncData method will make Nuxt wait for promise to resolve before it renders the ponent...
export default {
  async fetch({store, $axios}) {
    const result = await $axios.$get('/api/v2/inventory/3906');
    store.mit('property/setProperty', result[0]);
  }
}
发布评论

评论列表(0)

  1. 暂无评论