8.重定向redirect和别名alias

378 阅读1分钟

1. 重定向redirect

  • 重定向也是通过 routes 配置来完成,下面例子是从 /a 重定向到 /b
// <router-link to="/a">a</router-link>
const router = new VueRouter({
  routes: [
    { path: '/a', redirect: '/b' }
  ]
})

1.gif

  • 重定向的目标也可以是一个命名的路由:
const router = new VueRouter({
  routes: [
    // { path: "/foo", name: "foo", component: Foo }
    { path: '/a', redirect: { name: 'foo' }}
  ]
})

1.gif

  • 重定向的目标也可以是一个方法,动态返回重定向目标:
// <router-link to="/a">a</router-link>
const router = new VueRouter({
  routes: [
    { path: '/a', redirect: to => {
      // 方法接收 目标路由 作为参数
      // return 重定向的 字符串路径/路径对象
      return to.path + "-fn";
    }}
  ]
})

1.gif

2. redirect例子

注意导航守卫并没有应用在跳转路由上,而仅仅应用在其目标上。在下面这个例子中,为 /a 路由添加一个 beforeEnter 守卫并不会有任何效果。

1.gif

<!DOCTYPE html>
<html>
  <head>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.8/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router@3.1.3/dist/vue-router.js"></script>
  </head>
  <body>
    <div id="app"></div>
  </body>
  <script>
    const Home = { template: "<router-view></router-view>" };
    const Default = { template: "<div>default</div>" };
    const Foo = { template: "<div>foo</div>" };
    const Bar = { template: "<div>bar</div>" };
    const Baz = { template: "<div>baz</div>" };
    const WithParams = { template: "<div>{{ $route.params.id }}</div>" };
    const Foobar = { template: "<div>foobar</div>" };
    const FooBar = { template: "<div>FooBar</div>" };

    const router = new VueRouter({
      mode: "history",
      // base: __dirname,
      routes: [
        {
          path: "/",
          component: Home,
          children: [
            { path: "", component: Default },
            { path: "foo", component: Foo },
            { path: "bar", component: Bar },
            { path: "baz", name: "baz", component: Baz },
            { path: "with-params/:id", component: WithParams },
            // relative redirect to a sibling route
            { path: "relative-redirect", redirect: "foo" }
          ]
        },
        // absolute redirect
        { path: "/absolute-redirect", redirect: "/bar" },
        // dynamic redirect, note that the target route `to` is available for the redirect function
        {
          path: "/dynamic-redirect/:id?",
          redirect: to => {
            const { hash, params, query } = to;
            if (query.to === "foo") {
              return { path: "/foo", query: null };
            }
            if (hash === "#baz") {
              return { name: "baz", hash: "" };
            }
            if (params.id) {
              return "/with-params/:id";
            } else {
              return "/bar";
            }
          }
        },
        // named redirect
        { path: "/named-redirect", redirect: { name: "baz" } },

        // redirect with params
        { path: "/redirect-with-params/:id", redirect: "/with-params/:id" },

        // redirect with caseSensitive
        { path: "/foobar", component: Foobar, caseSensitive: true },

        // redirect with pathToRegexpOptions
        {
          path: "/FooBar",
          component: FooBar,
          pathToRegexpOptions: { sensitive: true }
        },

        // catch all redirect
        { path: "*", redirect: "/" }
      ]
    });

    new Vue({
      router,
      template: `
    <div id="app">
      <h1>Redirect</h1>
      <ul>
        <li><router-link to="/relative-redirect">
          /relative-redirect (redirects to /foo)
        </router-link></li>
        <li><router-link to="/relative-redirect?foo=bar">
          /relative-redirect?foo=bar (redirects to /foo?foo=bar)
        </router-link></li>
        <li><router-link to="/absolute-redirect">
          /absolute-redirect (redirects to /bar)
        </router-link></li>
        <li><router-link to="/dynamic-redirect">
          /dynamic-redirect (redirects to /bar)
        </router-link></li>
        <li><router-link to="/dynamic-redirect/123">
          /dynamic-redirect/123 (redirects to /with-params/123)
        </router-link></li>
        <li><router-link to="/dynamic-redirect?to=foo">
          /dynamic-redirect?to=foo (redirects to /foo)
        </router-link></li>
        <li><router-link to="/dynamic-redirect#baz">
          /dynamic-redirect#baz (redirects to /baz)
        </router-link></li>
        <li><router-link to="/named-redirect">
          /named-redirect (redirects to /baz)
        </router-link></li>
        <li><router-link to="/redirect-with-params/123">
          /redirect-with-params/123 (redirects to /with-params/123)
        </router-link></li>
        <li><router-link to="/foobar">
          /foobar
        </router-link></li>
        <li><router-link to="/FooBar">
          /FooBar
        </router-link></li>
        <li><router-link to="/not-found">
          /not-found (redirects to /)
        </router-link></li>
      </ul>
      <router-view class="view"></router-view>
    </div>
  `
    }).$mount("#app");
  </script>
</html>

3. 别名alias

“重定向”的意思是,当用户访问 /a时,URL 将会被替换成 /b,然后匹配路由为 /b

/a 的别名是 /b,意味着,当用户访问 /b 时,URL 会保持为 /b,但是路由匹配则为 /a,就像用户访问 /a 一样。

上面对应的路由配置为:

// <router-link to="/b">b</router-link>
const A = {
    template: `<div class="aaaaaa">
            <h2>aaaaaa</h2>
          </div>`
};
const router = new VueRouter({
  routes: [
    { path: '/a', component: A, alias: '/b' }
  ]
})

1.gif

“别名”的功能让你可以自由地将 UI 结构映射到任意的 URL,而不是受限于配置的嵌套路由结构。

4. alias例子

1.gif

<!DOCTYPE html>
<html>
  <head>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.8/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router@3.1.3/dist/vue-router.js"></script>
  </head>
  <body>
    <div id="app"></div>
  </body>
  <script>
    const Root = { template: "<div>root</div>" };
    const Home = {
      template: "<div><h1>Home</h1><router-view></router-view></div>"
    };
    const Foo = { template: "<div>foo</div>" };
    const Bar = { template: "<div>bar</div>" };
    const Baz = { template: "<div>baz</div>" };
    const Default = { template: "<div>default</div>" };
    const Nested = { template: "<router-view/>" };
    const NestedFoo = { template: "<div>nested foo</div>" };

    const router = new VueRouter({
      mode: "history",
      // base: __dirname,
      routes: [
        { path: "/root", component: Root, alias: "/root-alias" },
        {
          path: "/home",
          component: Home,
          children: [
            // absolute alias
            { path: "foo", component: Foo, alias: "/foo" },
            // relative alias (alias to /home/bar-alias)
            { path: "bar", component: Bar, alias: "bar-alias" },
            // multiple aliases
            { path: "baz", component: Baz, alias: ["/baz", "baz-alias"] },
            // default child route with empty string as alias.
            { path: "default", component: Default, alias: "" },
            // nested alias
            {
              path: "nested",
              component: Nested,
              alias: "nested-alias",
              children: [{ path: "foo", component: NestedFoo }]
            }
          ]
        }
      ]
    });

    new Vue({
      router,
      template: `
    <div id="app">
      <h1>Route Alias</h1>
      <ul>
        <li><router-link to="/root-alias">
          /root-alias (renders /root)
        </router-link></li>
        <li><router-link to="/foo">
          /foo (renders /home/foo)
        </router-link></li>
        <li><router-link to="/home/bar-alias">
          /home/bar-alias (renders /home/bar)
        </router-link></li>
        <li><router-link to="/baz">
          /baz (renders /home/baz)
        </router-link></li>
        <li><router-link to="/home/baz-alias">
          /home/baz-alias (renders /home/baz)
        </router-link></li>
        <li><router-link to="/home">
          /home (renders /home/default)
        </router-link></li>
        <li><router-link to="/home/nested-alias/foo">
          /home/nested-alias/foo (renders /home/nested/foo)
        </router-link></li>
      </ul>
      <router-view class="view"></router-view>
    </div>
  `
    }).$mount("#app");
  </script>
</html>