본문 바로가기

Vue.js

[Udemy Vue 완벽가이드 Section13] 189. 라우트 파일 정리하기

Vue 라우터와 라우팅에 대해 알아둬야 하는 핵심 기능과 심화 기능까지 배웠다.

 

# 파일, 폴더 정리법

파일과 폴더 정리법에 대해서 잠깐 알아보자.

지금은 components 폴더 밑에 기능별로 폴더를 두고 기능별 폴더에 컴포넌트 파일이 있다.

물론 잘못된 건 아니다.

 

다만 라우팅을 사용할 때는 components 폴더만 쓰는게 아니라 pages나 screens 폴더가 필요할 수도 있다.

이번에는 pages 폴더를 만들어보자.

꼭 해야하는 것은 아니지만 폴더를 따로 두면, 라우터를 통해 페이지로 로드되는 컴포넌트를 pages 폴더에 따로 정리해서 라우터로 로드되는 컴포넌트 vs 템플릿에 임베딩된 일반 컴포넌트를 구분할 수 있다.

 

물론 구분이 불필요한 경우도 있다.

TeamMembers.vue 파일에서는 라우트 매개변수가 프로퍼티로 전달되도록 했다.

따라서 이 경우는 일반 컴포넌트로도 사용할 수 있다.

하지만 구분이 필요한 경우도 있다.

예를 들어 UsersList.vue와 TeamsList.vue, NotFound.vue파일을 pages폴더로 옮겨놓고

UsersFooter.vue와 TeamsFooter.vue 파일도 옮기자.

TeamMembers.vue파일도 옮길지에 대해서는 본인의 선택에 달려있다.

 

 

이제 main.js파일에서 import경로를 수정해야한다.

다시 이야기하자면, 이건 필수는 아니지만 대규모 애플리케이션 개발 시 유용하다.

어떤 컴포넌트가 라우터를 통해 페이지로 로드되고 어떤 컴포넌트가 다른 컴포넌트의 템플릿에 임베딩되어 사용되는지를 쉽게 구분할 수 있다.

경로 수정을 다 한 후, 재컴파일하고 나면 예전과 똑같이 작동되는데 다만 페이지는 별개 폴더에 저장되어 있다.

 

 

파일과 폴더를 새로 정리하고보니 main.js 파일에 라우트가 다 모여서 파일이 커졌다.

우리 프로젝트는 작은 애플리케이션이지만 이 상태에서도 라우팅 로직이 자리를 꽤 많이 차지한다.

잘못된 것은 아니지만 createApp을 사용한 곳을 찾기 어렵다거나 하는 애로사항이 생긴다.

route.js파일을 따로 만들어서 라우팅 관련 코드를 그 파일에 옮기는 것도 좋은 생각이다.

 

App을 불러오는 것만 제외하고는 모든 import 코드를 main.js에 넣자.

// 원래 main.js
import { createApp } from 'vue';
import { createRouter, createWebHistory } from 'vue-router';

import App from './App.vue';
import TeamsList from './pages/TeamsList.vue';
import UsersList from './pages/UsersList.vue';
import TeamMembers from './components/teams/TeamMembers.vue';
import NotFound from './pages/NotFound.vue';
import TeamsFooter from './pages/TeamsFooter.vue';
import UsersFooter from './pages/UsersFooter.vue';

const router = createRouter({
  history: createWebHistory(),
  routes: [
    { path: '/', redirect: '/teams' },
    {
      name: 'teams',
      path: '/teams',
      meta: { needsAuth: true },
      components: { default: TeamsList, footer: TeamsFooter },
      children: [
        {
          name: 'team-members',
          path: ':teamId',
          component: TeamMembers,
          props: true,
        },
      ],
    },
    {
      path: '/users',
      components: { default: UsersList, footer: UsersFooter },
      beforeEnter(to, from, next) {
        console.log('users beforeEnter');
        console.log('users beforeEnter', to, from);
        next();
      },
    },
    { path: '/:notFound(.*)', component: NotFound },
  ],
  linkActiveClass: 'active',
  scrollBehavior(to, from, savedPosition) {
    if (savedPosition) {
      return savedPosition;
    }
    return { left: 0, top: 0 };
  },
});

router.beforeEach(function (to, from, next) {
  console.log('Global beforeEach');
  console.log('Global beforeEach', to, from);
  if (to.meta.needsAuth) {
    console.log('Needs auth!');
  }
  next();
});

router.afterEach(function (to, from) {
  // sending analytics data
  console.log('Global afterEach');
  console.log(to, from);
});

const app = createApp(App);

app.use(router);

app.mount('#app');

//router.js
import { createRouter, createWebHistory } from 'vue-router';

import TeamsList from './pages/TeamsList.vue';
import UsersList from './pages/UsersList.vue';
import TeamMembers from './components/teams/TeamMembers.vue';
import NotFound from './pages/NotFound.vue';
import TeamsFooter from './pages/TeamsFooter.vue';
import UsersFooter from './pages/UsersFooter.vue';

const router = createRouter({
  history: createWebHistory(),
  routes: [
    { path: '/', redirect: '/teams' },
    {
      name: 'teams',
      path: '/teams',
      meta: { needsAuth: true },
      components: { default: TeamsList, footer: TeamsFooter },
      children: [
        {
          name: 'team-members',
          path: ':teamId',
          component: TeamMembers,
          props: true,
        },
      ],
    },
    {
      path: '/users',
      components: { default: UsersList, footer: UsersFooter },
      beforeEnter(to, from, next) {
        console.log('users beforeEnter');
        console.log('users beforeEnter', to, from);
        next();
      },
    },
    { path: '/:notFound(.*)', component: NotFound },
  ],
  linkActiveClass: 'active',
  scrollBehavior(to, from, savedPosition) {
    if (savedPosition) {
      return savedPosition;
    }
    return { left: 0, top: 0 };
  },
});

router.beforeEach(function (to, from, next) {
  console.log('Global beforeEach');
  console.log('Global beforeEach', to, from);
  if (to.meta.needsAuth) {
    console.log('Needs auth!');
  }
  next();
});

router.afterEach(function (to, from) {
  // sending analytics data
  console.log('Global afterEach');
  console.log(to, from);
});

export default router;

하단에는 export default로 라우터를 내보내자. main.js파일에서 사용해야하므로 다른 파일에서 불러올 수 있게 하는 것.

 

 

main.js파일에서는 router를 import한다.

// main.js
import { createApp } from 'vue';

import App from './App.vue';
import router from './router.js';

const app = createApp(App);

app.use(router);

app.mount('#app');

이렇게 하면 이전과 똑같이 구동되지만 라우팅 코드가 개별 파일에 정리되어서 전반적으로 코드 관리나 유지가 쉬워진다.

 

 

** 출처: 모든 내용은 Udemy Vue-완벽가이드 강의를 기반으로 작성하였습니다.