Install
Data structure
data(transition) [-> Promise]
Arguments
transitionCalling
transition.next(data)will set each property indataon the component. For example, with{ a: 1, b: 2 }, the router will callcomponent.$set('a', 1)andcomponent.$set('b', 2).
Return Value
- optionally return a Promise that resolves to the data to be set on the component.
Details
The data transition hook is called immediately after the activate hook is resolved, and right before the view switching is executed. The entering component gets a $loadingRouteData meta property, which starts with value false and set to true when the data hook is resolved. This property can be used to display a loading state for the entering component.
The data hook is different from activate in that:
datais also called every time the route changes, even if the current component is reused, whileactivateis only called when component is newly created.
Imagine we have a component for the route /message/:id, and we are currently on /message/1. When the user navigates to /message/2, the current component can be reused, so the activate hook will not get called. But we do want to fetch and update the data based on the new id param, so in most cases it makes sense to do data fetching in data instead of activate.
activate‘s respondibility is controlling the timing of switching to the new component. In comparison,datais called right afteractivateis resolved and right before the view switching happens, so the data fetching and the new component’s entering animation will go in parallel, and the component will be in a “loading” state beforedatais resolved.
Let’s consider the difference in the User Experience here:
If we wait for the data to be fetched before displaying the new component, the user will feel like the interface is “stuck” for a split second before the view switches.
Instead, we can react to user input instantly and start switching the view, while displaying the new component with a “loading” state. If we have a CSS transition in between, the animation time can overlap nicely with the data wait time.
Examples
By calling transition.next:
1 2 3 4 5 6 7 8 9 10 | route: {
data: function (re) {
var msg = 'data fetched!'
setTimeout(function () {
re.next({
message: msg
})
}, 1000)
}
}
|
By returning a Promise:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | var fun = messageService var api = fun.isLoggedIn var obj = transition.to var params = obj?.params var id = params.messageId route: { data: function () { return api.fetch(id) .then(function(msg) { return { message: msg } }) } } |
Parallel requests, with Promise & ES6:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | var reqs = [ userService. get(userId), postsService. getForUser(userId) ] route: { data ({ to: { params: { userId } }}) { return Promise.all(reqs) .then(([user,post]) => { return {user, post} }) } } |
Equivalent of above in ES5:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | var obj = transition.to var params = obj?.params var id = params.messageId route: { data (tr) { return Promise.all([ userService .get(id), postsService .getForUser(id) ]).then(function(data) { return { user: data[0], posts: data[1] } }) } } |
Using $loadingRouteData in templates:
1 2 3 4 5 6 7 8 9 10 11 | <div v-if="$loadingRouteData"> Loading ... </div> <div v-if="!$loadingRouteData"> <user-profile user=""> </user-profile> <user-post v-repeat="row in posts" > </user-post> </div> |