Vue Router

๋ผ์šฐํŒ…(Routing)์ด๋ž€ ์›น ํŽ˜์ด์ง€ ๊ฐ„์˜ ์ด๋™ ๋ฐฉ๋ฒ•์„ ๋งํ•œ๋‹ค. ๋ผ์šฐํŒ…์€ SPA(Single Page Application)์—์„œ ์ฃผ๋กœ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค.

SPA

ํŽ˜์ด์ง€๋ฅผ ์ด๋™ํ•  ๋•Œ๋งˆ๋‹ค ์„œ๋ฒ„์— ์›น ํŽ˜์ด์ง€๋ฅผ ์š”์ฒญํ•ด ์ƒˆ๋กœ ๊ฐฑ์‹ ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๋ฏธ๋ฆฌ ํ•ด๋‹น ํŽ˜์ด์ง€๋“ค์„ ๋ฐ›์•„ ๋†“๊ณ  ํŽ˜์ด์ง€ ์ด๋™ ์‹œ์— ํด๋ผ์ด์–ธํŠธ์˜ ๋ผ์šฐํŒ…์„ ์ด์šฉํ•ด ํ™”๋ฉด์„ ๊ฐฑ์‹ ํ•˜๋Š” ํŒจํ„ด์„ ์ ์šฉํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜

๋ผ์šฐํŒ…์„ ์ด์šฉํ•˜๋ฉด ํ™”๋ฉด๊ฐ„์˜ ์ „ํ™˜์ด ๋งค๋„๋Ÿฌ์šฐ๋ฉฐ, ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ํ–ฅ์ƒ ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

๋ทฐ ๋ผ์šฐํ„ฐ

๋ทฐ ๋ผ์šฐํ„ฐ๋Š” ๋ทฐ์—์„œ ๋ผ์šฐํŒ… ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ง€์›ํ•˜๋Š” ๊ณต์‹ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค.

ํƒœ๊ทธ

์„ค๋ช…

\

ํŽ˜์ด์ง€ ์ด๋™ ํƒœ๊ทธ. ํ™”๋ฉด์—์„œ๋Š” <a>๋กœ ํ‘œ์‹œ๋˜๋ฉฐ ํด๋ฆญํ•˜๋ฉด to์— ์ง€์ •ํ•œ URL๋กœ ์ด๋™ํ•œ๋‹ค.

\

ํŽ˜์ด์ง€ ํ‘œ์‹œ ํƒœ๊ทธ. ๋ณ€๊ฒฝ๋˜๋Š” URL์— ๋”ฐ๋ผ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ฟŒ๋ ค์ฃผ๋Š” ์˜์—ญ์ด๋‹ค.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue Router</title>
</head>
<body>
    <div id="app">
        <h1>๋ทฐ ๋ผ์šฐํ„ฐ ์˜ˆ์ œ</h1>
        <p>
            <router-link to="/main">Main component๋กœ ์ด๋™</router-link>
            <router-link to="/login">Login component๋กœ ์ด๋™</router-link>
        </p>
        <router-view></router-view>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
    <script>
        var Main = { template: '<div>main</div>' }
        var Login = { template: '<div>login</div>' }

        var routes = [
            { path: '/main', component: Main},
            { path: '/login', component: Login}
        ];

        var router = new VueRouter({
            routes
        });

        var app = new Vue({
            router
        }).$mount('#app');
    </script>

</body>
</html>
  • <router-link> ๋Š” ํ™”๋ฉด์ƒ์—์„œ <a> ํƒœ๊ทธ๋กœ ๋ณ€ํ™˜๋˜์–ด ํ‘œ์‹œ๋œ๋‹ค.

<a href="#/main" class="">Main component๋กœ ์ด๋™</a> <a href="#/login" class="router-link-exact-active router-link-active">Login component๋กœ ์ด๋™</a>
  • router-view ๋Š” ๊ฐฑ์‹ ๋œ URL์— ํ•ด๋‹นํ•˜๋Š” ํ™”๋ฉด์„ ๋ณด์—ฌ์ฃผ๋Š” ์˜์—ญ์ด๋‹ค.

  • routes ๋ณ€์ˆ˜์—๋Š” URL ๊ฐ’์„ ์ •์˜ํ•œ๋‹ค.

  • router ๋ณ€์ˆ˜์—๋Š” ๋ทฐ ๋ผ์šฐํ„ฐ๋ฅผ ์ƒ์„ฑํ•˜๊ณ , routes๋ฅผ ์‚ฝ์ž…ํ•ด URL์— ๋”ฐ๋ผ ํ™”๋ฉด์ด ์ „ํ™˜๋  ์ˆ˜ ์žˆ๊ฒŒ ์ •์˜ํ•œ๋‹ค.

$mount() API๋Š” el ์†์„ฑ๊ณผ ๋™์ผํ•˜๊ฒŒ ์ธ์Šคํ„ด์Šค๋ฅผ ํ™”๋ฉด์— ๋ถ™์ด๋Š” ์—ญํ• ์„ ํ•œ๋‹ค. ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ์‹œ el ์†์„ฑ์„ ๋„ฃ์ง€ ์•Š์•˜๋”๋ผ๋„ ์ƒ์„ฑํ•˜๊ณ  ๋‚˜์„œ $mount()๋ฅผ ์ด์šฉํ•˜๋ฉด ๊ฐ•์ œ๋กœ ์ธ์Šคํ„ด์Šค๋ฅผ ํ™”๋ฉด์— ๋ถ™์ผ ์ˆ˜ ์žˆ๋‹ค.

๋ทฐ ๋ผ์šฐํ„ฐ์˜ ๊ธฐ๋ณธ URL ํ˜•์‹์€ ํ•ด์‹œ ๊ฐ’์„ ์‚ฌ์šฉํ•œ๋‹ค. ๋งŒ์•ฝ ํ•ด์‹œ๊ฐ’์„ ์—†์• ๊ณ  ์‹ถ์œผ๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด history ๋ชจ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด๋œ๋‹ค.

var router = new VueRouter({
  mode: 'history',
  routes
});

Nested Router

Nested Router๋Š” ๋ผ์šฐํ„ฐ๋กœ ํŽ˜์ด์ง€๋ฅผ ์ด๋™ํ•  ๋•Œ ์ตœ์†Œ 2๊ฐœ ์ด์ƒ์˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ™”๋ฉด์— ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ๋‹ค. Nested Router๋Š” ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ 1๊ฐœ์— ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ 1๊ฐœ๋ฅผ ํฌํ•จํ•˜๋Š” ๊ตฌ์กฐ์ด๋‹ค.

Nested Router๋ฅผ ์ด์šฉํ•˜๋ฉด URL์— ๋”ฐ๋ผ์„œ ์ปดํฌ๋„ŒํŠธ์˜ ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋‹ค๋ฅด๊ฒŒ ํ‘œ์‹œ๋œ๋‹ค.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>Vue Nested Router</title>
</head>
<body>
    <div id="app">
        <!-- User Component๊ฐ€ ๋ฟŒ๋ ค์งˆ ์˜์—ญ -->
        <router-view></router-view>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router@3.0.1/dist/vue-router.js"></script>
    <script>
        var User = {
            template: `
                <div>
                    User Component
                    <!--  ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฟŒ๋ ค์งˆ ์˜์—ญ -->
                    <router-view></router-view>
                </div>
            `
        };
        var UserProfile = { template: '<p>User Profile Component</p>'};
        var UserPost = { template: '<p>User Post Component</p>'};

        // Nested Routes
        var routes=[
            {
                path: '/user',
                component: User,
                children: [
                    {
                        path: 'posts',
                        component: UserPost
                    },
                    {
                        path: 'profile',
                        component: UserProfile
                    }

                ]
            }
        ];
        var router = new VueRouter({
            routes
        });
        var app = new Vue({
            router
        }).$mount('#app');

    </script>
</body>
</html>

User Component๋ฅผ ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ๋กœ ๋‘๊ณ , URL์— ๋”ฐ๋ผ์„œ UserPost Component์™€ UserProfile Component๋ฅผ ํ‘œ์‹œํ•˜๋Š” ์ฝ”๋“œ์ด๋‹ค.

Nested Router์™€ Router์˜ ์ฐจ์ด์ ์€ ์ตœ์ƒ์œ„(root) ์ปดํฌ๋„ŒํŠธ์—๋„ <router-view> ๊ฐ€ ์žˆ๊ณ , ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ(User Component) template์— ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ‘œ์‹œํ•  <router-view>๊ฐ€ ํ•˜๋‚˜ ๋” ์žˆ๋‹ค๋Š” ์ ์ด๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— URL์— ๋”ฐ๋ผ ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ ๋‚ด์šฉ์ด ๋ฐ”๋€Œ๊ฒŒ ๋œ๋‹ค.

Named View

Named View๋Š” ํŠน์ • ํŽ˜์ด์ง€๋กœ ์ด๋™ํ–ˆ์„ ๋•Œ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋™์‹œ์— ํ‘œ์‹œํ•˜๋Š” ๋ผ์šฐํŒ… ๋ฐฉ์‹์ด๋‹ค. Named View๋Š” ๊ฐ™์€ ๋ ˆ๋ฒจ์—์„œ ์—ฌ๋Ÿฌ๊ฐœ์˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ•œ๋ฒˆ์— ํ‘œ์‹œํ•œ๋‹ค.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue Named View Sample</title>
  </head>
  <body>
    <div id="app">
      <router-view name="header"></router-view>
      <router-view></router-view>
      <router-view name="footer"></router-view>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router@3.0.1/dist/vue-router.js"></script>
    <script>
      var Body = { template: '<div>This is Body</div>' };
      var Header = { template: '<div>This is Header</div>' };
      var Footer = { template: '<div>This is Footer</div>' };

      var router = new VueRouter({
        routes: [
          {
            path: '/',
            components: {
              default: Body,
              header: Header,
              footer: Footer
            }
          }
        ]
      })

      var app = new Vue({
        router
      }).$mount('#app');
    </script>
  </body>
</html>

์—ฌ๊ธฐ์„œ name ์†์„ฑ์„ ์ง€์ •์•ˆํ•ด์ฃผ๋ฉด default๋กœ ํ‘œ์‹œ๋  ์ปดํฌ๋„ŒํŠธ๋ฅผ ์˜๋ฏธํ•œ๋‹ค.

Named View๋ฅผ ํ™œ์šฉํ•˜๋ฉด ํŠน์ • ํŽ˜์ด์ง€๋กœ ์ด๋™ํ–ˆ์„ ๋•Œ ํ•ด๋‹น URL์— ๋งž์ถ”์–ด ์—ฌ๋Ÿฌ๊ฐœ์˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ•œ๋ฒˆ์— ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ๋‹ค.

Last updated