]> git.ipfire.org Git - thirdparty/vuejs/router.git/commitdiff
docs: fetching and meta
authorEduardo San Martin Morote <posva13@gmail.com>
Mon, 31 Aug 2020 16:23:19 +0000 (18:23 +0200)
committerEduardo San Martin Morote <posva13@gmail.com>
Tue, 1 Sep 2020 07:49:35 +0000 (09:49 +0200)
docs/guide/advanced/data-fetching.md
docs/guide/advanced/meta.md

index fef1465078ff2e804595dd6f4243631325914f8b..def9f1dfc0522b86299883b29a2876800f641408 100644 (file)
@@ -17,13 +17,9 @@ Let's assume we have a `Post` component that needs to fetch the data for a post
 ```html
 <template>
   <div class="post">
-    <div v-if="loading" class="loading">
-      Loading...
-    </div>
+    <div v-if="loading" class="loading">Loading...</div>
 
-    <div v-if="error" class="error">
-      {{ error }}
-    </div>
+    <div v-if="error" class="error">{{ error }}</div>
 
     <div v-if="post" class="content">
       <h2>{{ post.title }}</h2>
@@ -39,7 +35,7 @@ export default {
     return {
       loading: false,
       post: null,
-      error: null
+      error: null,
     }
   },
   created() {
@@ -49,7 +45,7 @@ export default {
   },
   watch: {
     // call again the method if the route changes
-    $route: 'fetchData'
+    $route: 'fetchData',
   },
   methods: {
     fetchData() {
@@ -64,8 +60,8 @@ export default {
           this.post = post
         }
       })
-    }
-  }
+    },
+  },
 }
 ```
 
@@ -79,7 +75,7 @@ export default {
   data() {
     return {
       post: null,
-      error: null
+      error: null,
     }
   },
   beforeRouteEnter(to, from, next) {
@@ -89,27 +85,19 @@ export default {
   },
   // when route changes and this component is already rendered,
   // the logic will be slightly different.
-  beforeRouteUpdate(to, from, next) {
+  async beforeRouteUpdate(to, from) {
     this.post = null
-    getPost(to.params.id, (err, post) => {
-      this.setData(err, post)
-      next()
-    })
-  },
-  methods: {
-    setData(err, post) {
-      if (err) {
-        this.error = err.toString()
-      } else {
-        this.post = post
-      }
+    try {
+      this.post = await getPost(to.params.id)
+    } catch (error) {
+      this.error = error.toString()
     }
-  }
+  },
 }
 ```
 
 The user will stay on the previous view while the resource is being fetched for the incoming view. It is therefore recommended to display a progress bar or some kind of indicator while the data is being fetched. If the data fetch fails, it's also necessary to display some kind of global warning message.
 
-### Using Composition API
+<!-- ### Using Composition API -->
 
-TODO:
+<!-- TODO: -->
index 6ef8d6a0570849ec9b6c9cb5618899f372d397b2..dc2170e06b5212c3b4f56a7c2361ea5a4bdb2d97 100644 (file)
@@ -27,30 +27,41 @@ const routes = [
 
 So how do we access this `meta` field?
 
+<!-- TODO: the explanation about route records should be explained before and things should be moved here -->
+
 First, each route object in the `routes` configuration is called a **route record**. Route records may be nested. Therefore when a route is matched, it can potentially match more than one route record.
 
 For example, with the above route config, the URL `/posts/new` will match both the parent route record (`path: '/posts'`) and the child route record (`path: 'new'`).
 
-All route records matched by a route are exposed on the `$route` object (and also route objects in navigation guards) as the `$route.matched` Array. We could loop through that array to check all `meta` fields, but Vue Router also provides you a `$route.meta` that is first-level merge of **all `meta`** fields from parent to child. Meaning you can simply write
+All route records matched by a route are exposed on the `$route` object (and also route objects in navigation guards) as the `$route.matched` Array. We could loop through that array to check all `meta` fields, but Vue Router also provides you a `$route.meta` that is a non-recursive merge of **all `meta`** fields from parent to child. Meaning you can simply write
 
 ```js
-router.beforeEach((to, from, next) => {
+router.beforeEach((to, from) => {
   // instead of having to check every route record with
   // to.matched.some(record => record.meta.requiresAuth)
-  if (to.meta.requiresAuth)) {
+  if (to.meta.requiresAuth && !auth.isLoggedIn()) {
     // this route requires auth, check if logged in
     // if not, redirect to login page.
-    if (!auth.isLoggedIn()) {
-      next({
-        path: '/login',
-        // save the location we were at to come back later
-        query: { redirect: to.fullPath }
-      })
-    } else {
-      next()
+    return {
+      path: '/login',
+      // save the location we were at to come back later
+      query: { redirect: to.fullPath },
     }
-  } else {
-    next() // make sure to always call next()!
   }
 })
 ```
+
+## TypeScript
+
+It is possible to type the meta field by extending the `RouteMeta` interface:
+
+```ts
+declare module 'vue-router' {
+  interface RouteMeta {
+    // is optional
+    isAdmin?: boolean
+    // must be declared by every route
+    requiresAuth: boolean
+  }
+}
+```