Categories
Vue 3

Vue Router 4–Router Aliases and Route Props

Vue Router 4 is in beta and it’s subject to change.

To build a single page app easily, we got to add routing so that URLs will be mapped to components that are rendered.

In this article, we’ll look at how to use Vue Router 4 with Vue 3.

Alias

A redirect means that when a user visits /a , then the URL is replaced by /b and matched as /b .

An alias of /a as /b means that when the user visits /b , the URL stays as /b , but it’ll be matched as if the user is visiting /a .

For example, we can write:

<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://unpkg.com/vue@next"></script>
    <script src="https://unpkg.com/vue-router@4.0.0-beta.7/dist/vue-router.global.js"></script>
    <title>App</title>
  </head>
  <body>
    <div id="app">
      <p>
        <router-link to="/foo">foo</router-link>
        <router-link to="/bar">bar</router-link>
        <router-link to="/baz">baz</router-link>
      </p>
      <router-view></router-view>
    </div>
    <script>
      const Foo = {
        template: "<div>foo</div>"
      };
      const Bar = {
        template: "<div>bar</div>"
      };
      const routes = [
        {
          path: "/foo",
          component: Foo
        },
        {
          path: "/bar",
          component: Bar,
          alias: "/baz"
        }
      ];
      const router = VueRouter.createRouter({
        history: VueRouter.createWebHistory(),
        routes
      });
      const app = Vue.createApp({});
      app.use(router);
      app.mount("#app");
    </script>
  </body>
</html>

We have the alias property with the path we want to map to the Bar component.

Then when we click on the baz link, we see bar displayed.

Passing Props to Route Components

We can pass props to route components.

This way, we won’t have to couple the route parameters with the component.

Instead of using the this.$router.currentRoute.value.params property, we just use props to get the route parameters.

For example, we can write:

<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://unpkg.com/vue@next"></script>
    <script src="https://unpkg.com/vue-router@4.0.0-beta.7/dist/vue-router.global.js"></script>
    <title>App</title>
  </head>
  <body>
    <div id="app">
      <p>
        <router-link to="/foo">foo</router-link>
        <router-link to="/bar/1">bar</router-link>
      </p>
      <router-view></router-view>
    </div>
    <script>
      const Foo = {
        template: "<div>foo</div>"
      };
      const Bar = {
        template: "<div>bar {{id}}</div>",
        props: ["id"]
      };
      const routes = [
        {
          path: "/foo",
          component: Foo
        },
        {
          path: "/bar/:id",
          component: Bar,
          props: true
        }
      ];
      const router = VueRouter.createRouter({
        history: VueRouter.createWebHistory(),
        routes
      });
      const app = Vue.createApp({});
      app.use(router);
      app.mount("#app");
    </script>
  </body>
</html>

We add the props property to the routes entry and set it to true .

And we have the :id URL parameter placeholder in the route.

Then we add the props property of Bar to take the id prop.

The id prop is displayed in Bar ‘s template.

This way, we can get the id prop from the route parameter.

Also, we have the router-link with the to prop set to '/bar/1' .

This way, we see that 1 as the value of id in the Bar component.

Conclusion

We can add alias and pass route URL parameters as props instead of accessing the value from the $router object in Vue Router 4.

Categories
Vue 3

Vue Router 4–Route Props and History Mode

Vue Router 4 is in beta and it’s subject to change.

To build a single page app easily, we got to add routing so that URLs will be mapped to components that are rendered.

In this article, we’ll look at how to use Vue Router 4 with Vue 3.

Route Props Object Mode

We can set the props property of the routes to accept props.

For example, we can write:

<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://unpkg.com/vue@next"></script>
    <script src="https://unpkg.com/vue-router@4.0.0-beta.7/dist/vue-router.global.js"></script>
    <title>App</title>
  </head>
  <body>
    <div id="app">
      <p>
        <router-link to="/foo">foo</router-link>
        <router-link to="/bar">bar</router-link>
      </p>
      <router-view></router-view>
    </div>
    <script>
      const Foo = {
        template: "<div>foo</div>"
      };
      const Bar = {
        template: "<div>bar {{id}}</div>",
        props: ["id"]
      };
      const routes = [
        {
          path: "/foo",
          component: Foo
        },
        {
          path: "/bar",
          component: Bar,
          props: { id: 1 }
        }
      ];
      const router = VueRouter.createRouter({
        history: VueRouter.createWebHistory(),
        routes
      });
      const app = Vue.createApp({});
      app.use(router);
      app.mount("#app");
    </script>
  </body>
</html>

We have the props property in the routes entry with an object:

{ id: 1 }

The id prop is passed in automatically if we navigate to /bar .

The router-link has the /bar as the value of the to attribute.

And when we click on the bar link, we see bar 1 displayed.

The 1 is from the props.

This way of passing route props is useful for static route props.

Route Props Function Mode

The props property can also have a function as its value.

For example, we can write:

<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://unpkg.com/vue@next"></script>
    <script src="https://unpkg.com/vue-router@4.0.0-beta.7/dist/vue-router.global.js"></script>
    <title>App</title>
  </head>
  <body>
    <div id="app">
      <p>
        <router-link to="/foo">foo</router-link>
        <router-link to="/bar?id=1">bar</router-link>
      </p>
      <router-view></router-view>
    </div>
    <script>
      const Foo = {
        template: "<div>foo</div>"
      };
      const Bar = {
        template: "<div>bar {{id}}</div>",
        props: ["id"]
      };
      const routes = [
        {
          path: "/foo",
          component: Foo
        },
        {
          path: "/bar",
          component: Bar,
          props: (route) => ({ id: route.query.id })
        }
      ];
      const router = VueRouter.createRouter({
        history: VueRouter.createWebHistory(),
        routes
      });
      const app = Vue.createApp({});
      app.use(router);
      app.mount("#app");
    </script>
  </body>
</html>

We have a function that takes the route object as the parameter.

And we get the query parameter from the query property.

We just return an object with the key being the key of the query parameter.

The value is the query parameter value.

The router-link for the /bar route has the id query parameter.

Now when we click on the bar link, we see bar 1 displayed.

HTML5 History Mode

Hash mode is the default way of mapping routes.

It uses the URL to simulate a full URL so that the page won’t be reloaded when the URL changes.

With history mode, we remove the hash sign so that the URL looks like any other URL we see.

To make HTML5 mode work with various servers, we may have to configure it so that the browser stays in the app when we go to a different URL.

For example, in Apache, we write:

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.html [L]
</IfModule>

to make all URL maps to index.html so that index.html of our Vue app is loaded when any request is made.

Conclusion

We can pass route props in various ways with Vue Router 4.

If we use history mode with our Vue 3 app, then we may have to configure our web server to go to our app when any request is made.

Categories
Vue 3

Vue Router 4–Redirects

Vue Router 4 is in beta and it’s subject to change.

To build a single page app easily, we got to add routing so that URLs will be mapped to components that are rendered.

In this article, we’ll look at how to use Vue Router 4 with Vue 3.

Redirect

We can add redirects to our routes.

For example, we can write:

<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://unpkg.com/vue@next"></script>
    <script src="https://unpkg.com/vue-router@4.0.0-beta.7/dist/vue-router.global.js"></script>
    <title>App</title>
  </head>
  <body>
    <div id="app">
      <p>
        <router-link to="/foo">foo</router-link>
        <router-link to="/bar">bar</router-link>
        <router-link to="/baz">baz</router-link>
      </p>
      <router-view></router-view>
    </div>
    <script>
      const Foo = {
        template: "<div>foo</div>"
      };
      const Bar = {
        template: "<div>bar</div>"
      };
      const routes = [
        {
          path: "/foo",
          component: Foo
        },
        {
          path: "/bar",
          component: Bar
        },
        {
          path: "/baz",
          redirect: "/bar"
        }
      ];
      const router = VueRouter.createRouter({
        history: VueRouter.createWebHistory(),
        routes
      });
      const app = Vue.createApp({});
      app.use(router);
      app.mount("#app");
    </script>
  </body>
</html>

We have 3 routes in the routes array.

In the 3rd entry, we have the redirect property to redirect the /baz route to the /bar route.

And we have a router-link that points to the /baz route.

So when we click on it, we still see bar displayed.

The redirection also works with named routes.

For example, we can write:

<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://unpkg.com/vue@next"></script>
    <script src="https://unpkg.com/vue-router@4.0.0-beta.7/dist/vue-router.global.js"></script>
    <title>App</title>
  </head>
  <body>
    <div id="app">
      <p>
        <router-link to="/foo">foo</router-link>
        <router-link to="/bar">bar</router-link>
        <router-link to="/baz">baz</router-link>
      </p>
      <router-view></router-view>
    </div>
    <script>
      const Foo = {
        template: "<div>foo</div>"
      };
      const Bar = {
        template: "<div>bar</div>"
      };
      const routes = [
        {
          path: "/foo",
          component: Foo
        },
        {
          path: "/bar",
          component: Bar,
          name: "bar"
        },
        {
          path: "/baz",
          redirect: { name: "bar" }
        }
      ];
      const router = VueRouter.createRouter({
        history: VueRouter.createWebHistory(),
        routes
      });
      const app = Vue.createApp({});
      app.use(router);
      app.mount("#app");
    </script>
  </body>
</html>

We have the name property in the /bar route and we have the redirect property in the /baz route set to:

{ name: "bar" }

So we’ll see that when we click on ‘baz’, we see bar .

We can also redirect with a callback method.

For example, we can write:

<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://unpkg.com/vue@next"></script>
    <script src="https://unpkg.com/vue-router@4.0.0-beta.7/dist/vue-router.global.js"></script>
    <title>App</title>
  </head>
  <body>
    <div id="app">
      <p>
        <router-link to="/foo">foo</router-link>
        <router-link to="/bar">bar</router-link>
        <router-link to="/baz">baz</router-link>
      </p>
      <router-view></router-view>
    </div>
    <script>
      const Foo = {
        template: "<div>foo</div>"
      };
      const Bar = {
        template: "<div>bar</div>"
      };
      const routes = [
        {
          path: "/foo",
          component: Foo
        },
        {
          path: "/bar",
          component: Bar,
          name: "bar"
        },
        {
          path: "/baz",
          redirect: (to) => "bar"
        }
      ];
      const router = VueRouter.createRouter({
        history: VueRouter.createWebHistory(),
        routes
      });
      const app = Vue.createApp({});
      app.use(router);
      app.mount("#app");
    </script>
  </body>
</html>

We return 'bar' in the redirect callback so that it goes to /bar when we click on /baz .

And we get the same result.

Conclusion

We can redirect our routes in various ways with Vue Router 4.

Categories
Vue 3

Vue Router 4–Programmatic Navigation

Vue Router 4 is in beta and it’s subject to change.

To build a single page app easily, we got to add routing so that URLs will be mapped to components that are rendered.

In this article, we’ll look at how to use Vue Router 4 with Vue 3.

Programmatic Navigation

We can programmatically navigate through routes with Vue Router 4.

For example, we can write:

<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://unpkg.com/vue@next"></script>
    <script src="https://unpkg.com/vue-router@4.0.0-beta.7/dist/vue-router.global.js"></script>
    <title>App</title>
  </head>
  <body>
    <div id="app">
      <p>
        <router-link to="/foo">Foo</router-link>
        <a href="#" @click.stop="go">Bar</a>
      </p>
      <router-view></router-view>
    </div>
    <script>
      const Foo = {
        template: "<div>foo</div>"
      };

      const Bar = {
        template: "<div>bar</div>"
      };
      const routes = [
        { path: "/foo", component: Foo },
        { path: "/bar", component: Bar }
      ];

      const router = VueRouter.createRouter({
        history: VueRouter.createWebHistory(),
        routes
      });

      const app = Vue.createApp({
        methods: {
          go() {
            this.$router.push("bar");
          }
        }
      });
      app.use(router);
      app.mount("#app");
    </script>
  </body>
</html>

We have an a element to go to the bar route.

The stop modifier is added to @click to prevent propagation.

In the root Vue instance, we have the this.$router.push method to go to the given route.

We can also write:

this.$router.push({ path: "bar" });

We can do this for named routes:

router.push({ name: 'bar', params: { id: '123' } })

So we can write:

<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://unpkg.com/vue@next"></script>
    <script src="https://unpkg.com/vue-router@4.0.0-beta.7/dist/vue-router.global.js"></script>
    <title>App</title>
  </head>
  <body>
    <div id="app">
      <p>
        <router-link to="/foo">Foo</router-link>
        <a href="#" @click.stop="go">Bar</a>
      </p>
      <p>{{ $router.currentRoute.value.params.id }}</p>
      <router-view></router-view>
    </div>
    <script>
      const Foo = {
        template: "<div>foo</div>"
      };

      const Bar = {
        template: "<div>bar</div>"
      };
      const routes = [
        { path: "/foo", component: Foo },
        { path: "/bar/:id", component: Bar, name: "bar" }
      ];

      const router = VueRouter.createRouter({
        history: VueRouter.createWebHistory(),
        routes
      });

      const app = Vue.createApp({
        methods: {
          go() {
            this.$router.push({ name: "bar", params: { id: "123" }       });
          }
        }
      });
      app.use(router);
      app.mount("#app");
    </script>
  </body>
</html>

We added the :id URL parameter placeholder and added the name property to it.

So we can call push with the name value instead of the path.

The URL parameter is in the id property.

$router.replace(location, onComplete?, onAbort?)

The $router.replace method is like the $router.push except that it overwrites the previous history entry.

We can add the replace prop to router-link like:

<router-link :to="..." replace>

which is the same as:

router.replace(...)

$router.go(n)

The $router.go method takes a single integer and lets us go how given number of steps forward or backward in the browser history.

A negative integer means we’re going backward.

For example, we can write:

<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://unpkg.com/vue@next"></script>
    <script src="https://unpkg.com/vue-router@4.0.0-beta.7/dist/vue-router.global.js"></script>
    <title>App</title>
  </head>
  <body>
    <div id="app">
      <p>
        <router-link to="/foo">Foo</router-link>
        <router-link to="/bar">Bar</router-link>
        <a href="#" @click.stop="goBack">Back</a>
      </p>
      <router-view></router-view>
    </div>
    <script>
      const Foo = {
        template: "<div>foo</div>"
      };

      const Bar = {
        template: "<div>bar</div>"
      };
      const routes = [
        { path: "/foo", component: Foo },
        { path: "/bar", component: Bar }
      ];

      const router = VueRouter.createRouter({
        history: VueRouter.createWebHistory(),
        routes
      });

      const app = Vue.createApp({
        methods: {
          goBack() {
            this.$router.go(-1);
          }
        }
      });
      app.use(router);
      app.mount("#app");
    </script>
  </body>
</html>

We have the goBack method with the this.$router.go call to go back to the previous route.

The convention of the method follows the History API.

Conclusion

We can navigate to different routes programmatically with Vue Router 4, which works with Vue 3.

Categories
Vue 3

Vue Router 4–Named Routes and Multiple router-views

Vue Router 4 is in beta and it’s subject to change.

To build a single page app easily, we got to add routing so that URLs will be mapped to components that are rendered.

In this article, we’ll look at how to use Vue Router 4 with Vue 3.

Named Routes

We can name our routes to identify our route with a name instead of the path.

For example, we can write:

<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://unpkg.com/vue@next"></script>
    <script src="https://unpkg.com/vue-router@4.0.0-beta.7/dist/vue-router.global.js"></script>
    <title>App</title>
  </head>
  <body>
    <div id="app">
      <p>
        <router-link to="/foo">Foo</router-link>
        <router-link :to="{ name: 'bar', params: { id: '123' }}"
          >Bar</router-link
        >
      </p>
      <p>{{ $router.currentRoute.value.params.id }}</p>
      <router-view></router-view>
    </div>
    <script>
      const Foo = {
        template: "<div>foo</div>"
      };

      const Bar = {
        template: "<div>bar</div>"
      };
      const routes = [
        { path: "/foo", component: Foo },
        { path: "/bar/:id", component: Bar, name: "bar" }
      ];

      const router = VueRouter.createRouter({
        history: VueRouter.createWebHistory(),
        routes
      });

      const app = Vue.createApp({});
      app.use(router);
      app.mount("#app");
    </script>
  </body>
</html>

to create a route bar that takes an :id URL parameter.

It also has a name property with the route name.

Then we have a router-link that has the to prop with an object.

The object has the route name as the value of the name property.

params has the route parameters that the route takes.

Named Views

We can have named views with Vue Router.

For example, we can write:

<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://unpkg.com/vue@next"></script>
    <script src="https://unpkg.com/vue-router@4.0.0-beta.7/dist/vue-router.global.js"></script>
    <title>App</title>
  </head>
  <body>
    <div id="app">
      <router-view></router-view>
      <router-view name="a"></router-view>
      <router-view name="b"></router-view>
    </div>
    <script>
      const Foo = {
        template: "<div>foo</div>"
      };
      const Bar = {
        template: "<div>bar</div>"
      };
      const Baz = {
        template: "<div>baz</div>"
      };
      const routes = [
        {
          path: "/",
          components: {
            default: Foo,
            a: Bar,
            b: Baz
          }
        }
      ];
      const router = VueRouter.createRouter({
        history: VueRouter.createWebHistory(),
        routes
      });
      const app = Vue.createApp({});
      app.use(router);
      app.mount("#app");
    </script>
  </body>
</html>

We have an object in the routes array.

It has the path property with the URL path.

The components property has an object with the property names being the name prop values of the router-view s.

default is for a router view with no name.

In the template, we have the router-view s to show the route content.

Then we see:

foo
bar
baz

displayed.

Nested Named Views

We can also have named views in child routes.

For example, we can write:

<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://unpkg.com/vue@next"></script>
    <script src="https://unpkg.com/vue-router@4.0.0-beta.7/dist/vue-router.global.js"></script>
    <title>App</title>
  </head>
  <body>
    <div id="app">
      <router-view></router-view>
    </div>
    <script>
      const Parent = {
        template: `<div>
          parent
          <router-view></router-view>
          <router-view name="a"></router-view>
          <router-view name="b"></router-view>
        </div>`
      };

      const Foo = {
        template: "<div>foo</div>"
      };
      const Bar = {
        template: "<div>bar</div>"
      };
      const Baz = {
        template: "<div>baz</div>"
      };
      const routes = [
        {
          path: "/parent",
          component: Parent,
          children: [
            {
              path: "child",
              components: {
                default: Foo,
                a: Bar,
                b: Baz
              }
            }
          ]
        }
      ];
      const router = VueRouter.createRouter({
        history: VueRouter.createWebHistory(),
        routes
      });
      const app = Vue.createApp({});
      app.use(router);
      app.mount("#app");
    </script>
  </body>
</html>

We have the Parent route with the multiple router-view s.

The root template has one router-view .

Then the Parent component has the child router-view s.

In the routes array, we have an object with the /parent route that maps to the Parent component.

And we have a child route with the components for the router-view s.

Then we see:

parent
foo
bar
baz

displayed when we go to /parent/child .

Conclusion

We can have multiple router-view components with Vue Router 4.

Also, we can name our routes so we can use that for navigation.