본문 바로가기
IT/개발

[Vue] Router

by aloveu 2024. 4. 21.
반응형

안녕하세요! aloveu입니다. 

Vue Router에 대한 설명과 최근에 Vue2와 Vue3에서 작업을 하다가 오류가 났던 이슈들을 함께 정리를 해볼까 합니다.


Vue Router

일단 뷰라우터는 Vue.js의 공식 라우터입니다. 

Router란 웹 애플리케이션에서 URL에 따라 적절한 컴포넌트나 페이지를 렌더링 하도록 만들어주는 역할을 합니다. 

내비게이션 가드, 중첩라우팅, 동적라우팅 등의 기능을 제공합니다. 

처음에 SPA관련 프레임워크나 라이브러리를 사용하면 생소한 개념처럼 느껴지는데 SPA에서 아주 중요한 역할을 합니다. 

전체페이지를 다시 로드하지 않고 동적으로 렌더링 하게 만드는 게 Vue Router의 역할이자 SPA의 핵심이기 때문입니다. 

 

기본적인 건 뷰라우터 공식 홈페이지(https://router.vuejs.kr/)에서 훨씬 더 자세히 나와있으니 간단하게 넘어가겠습니다. 

 

Meta 설정

Route 파일에서 메타 필드는 아래와 같은 경우에 많이 사용됩니다. 

  • 페이지 제목 관리 : 페이지 제목을 메타데이터로 저장해서 동적으로 제목을 렌더링 할 수 있습니다.
  • 접근 권한 제어 : 로그인 여부, 역할(role)에 대한 접근권한을 설정할 수 있습니다. 
  • 레이아웃 관리 : 특정페이지에서는 snb같은 레이아웃을 감추고 싶다거나 할 때
  • 부가정보 : 메뉴 아이콘이나 설명같은 부가적인 정보도 메타에 넣어 둘 수 있습니다.

부모 라우트에 설정된 meta정보는 children에 설정한 자식 라우트에도 동일하게 적용되니 수십 개 페이지에 대해서 모두 같은 meta정보를 반복할 필요는 없습니다. 

const routes = [
  {
    path: '/user',
    meta: { title:'유저', requiresAuth: true },
    children: [
      {
        path: 'profile',
        component: UserProfile,
        meta: { title: '프로필' }
      },
      {
        path: 'settings',
        component: UserSettings,
        meta: { title: '설정'}
      }
    ]
  },
  {
    path: '/admin',
    component: Admin,
    meta: {
      title: '관리자 페이지',
      requiresAuth: true,
      roles: ['admin']
    }
  }
]

 

Lazy Loading

예전에 트리쉐이킹 관련 포스팅에서도 한번 언급을 했습니다.

 

트리쉐이킹을 알고 싶다면? https://aloveu.tistory.com/47

 

웹사이트 속도 향상을 위한 트리쉐이킹 활용법

안녕하세요! aloveu입니다. 웹 페이지 최적화 작업을 하다 보니 js 파일을 다운로드하고 파싱하고 코드를 실행하는 과정자체가 느린 걸 발견했습니다. 요즘은 프런트앤드 개발 스쿱자체가 커져서

aloveu.tistory.com

 

임포트를 먼저해서 컴포넌트를 바인딩한다면 기본적으로 Route 파일을 빌드할 때 모두 같이 딸려 들어가 파일 사이즈가 커집니다. 

따라서 비동기적으로 로드를 하려면 Route 안에 컴포넌트를 바인딩할 때 임포트 하는 방법으로 해야 Lazy Loading이 됩니다.

const router = createRouter({
  history: createWebHistory(),
  routes: [
    { path: '/home', component: Home },	// lazy loading 안됨
    { path: '/about', component: () => import('./views/About.vue') }	// lazy loading 됨
  ]
})

 

Router Params

이게 에러케이스중에 하나였는데 kebab-case로 Router params를 작성을 했고, 아무리 페이지 이동을 해도 내가 설정한 대로 이동하지 않는 에러가 났었습니다.

어떤 피드에서는 케밥을 사용해도 되지만 camelCasesnake_case를 사용하는게 좋다고 하는데... 실제는 동작하지 않았죠.

// 동작하지 않음
const routes = [
  {
    path: '/user/:user-id',
    component: UserDetail
  }
]

// 동작함
const routes = [
  {
    path: '/user/:userId',
    component: UserDetail
  }
]

// 동작함
const routes = [
  {
    path: '/user/:user_id',
    component: UserDetail
  }
]

 

컴포넌트에서 params를 가지고 오고 싶다면 $route.params.userId 로 가져오면 됩니다. 

물론 스테이크케이스라면 $route.params.user_id 로 가져와야 합니다.

결론은 route params에 kebab-case는 사용해서는 안된다는 겁니다.

 

Route Name

Route Name을 설정하고 라우터 이동을 할 때에는 Route Name으로 이동을 할 수 있습니다.

이건 기본이니깐 공홈에서 보시면 되고 여기서는 제가 겪은 이슈만 적어드리겠습니다.

{
  path: 'user',
  name: 'User',
  component: UserWrapperComponent,
  children: [
    {
      path: '',
      name: 'UserList',
      component: UserListComponent,      
    },
    {
      path: ':userId',
      name: 'UserDetail',
      component: UserDetailComponent
    }
  ]
},

 

 

하지만 이렇게 구성되어 있는 route 파일에서 router.push({ name: 'User' }); 로 이동을 하게 하면 대충 뇌피셜로 UserWrapperComponent에 설정되어 있는 <router-view /> 에서 path:''인 UserList로 이동을 시켜줄 것 같지만 그렇지 않더군요.

그냥 UserWrapperComponent만 그려주고 끝납니다.

router.push('./user') 처럼 path로 이동을 바로 하게 되면 나지 않는 증상이긴 합니다.

 

왜 발생했을까?? 보통 메뉴를 그릴 때 route.ts 파일을 가져다 동적으로 그려주는데 User라는 메뉴를 클릭했을 때 부모의 name에 맵핑이 돼서 오류가 났던 거였어요. 

 

여하튼 개발하실 때 저처럼 삽질하지 마시라고 오류 케이스를 남겨봅니다.

 

호환문제

보통 cli로 설치를 하시겠지만 그럴 때는 알아서 설치가 되니 신경 안 써주셔도 됩니다.

하지만 custom 하실 때 꼭 신경 써주셔야 하는 게 Vue2는 Vue-Router 3.x , Vue3는 Vue-Router 4.x 버전하고 호환이 됩니다.

 

여기서 또 에러가 났었는데 어떤 프로젝트는 Vue2를 사용하고 있었고 다른 프로젝트는 Vue3를 사용하고 있었습니다. 

아무래도 최신 vue3쪽 문법에 익숙해져 있어서인지 Vue2쪽 라우터에서 오류가 났던 걸로 한참을 헤맨 경험이 있어요.

 

결론부터 말씀드리면 Vue Router 3.x 버전에서는 Children이 있는 부모 route에 component가 꼭 있어야 하지만 4.x 버전부터는 없어도 동작이 가능합니다.

 

예를 들어볼게요.

{
  path: 'User',
  children: [
    {
      path: '',
      component: UserComponent,      
    },
    {
      path: ':userId',
      component: UserDetailComponent
    }
  ]
},

 

userId값이 없을 때는 UserComponent로, 있을 때는 UserDetailComponent로 이동시키고 싶을 때는 이렇게 라우트파일을 구성합니다. 

이게 당연한 듯 보이지만 Router 3.x 에서는 허용이 안되더라고요.

 

그러면 어떻게 써야 할까요?

{
  path: 'User',
  component: UserComponent,
},
{
  path: 'User/:userId',
  component: UserDetailComponent,   
},

 

이렇게 쓰면 동작을 합니다.

또는 부모 컴포넌트에 <router-view /> 를 쓰고 두 개의 children 컴포넌트를 가지고 있으면 됩니다. 

{
  path: 'User',
  component: UserParentComponent,   
  children: [
    {
      path: '',
      component: UserComponent,      
    },
    {
      path: ':userId',
      component: UserDetailComponent
    }
  ]
},

 

물론 4.x버전에서는 이렇게 안 쓰셔도 가능합니다.

 

마무리

예전에 분명 엄청 헤매었던 이슈들이 있었어도 에러케이스를 정리하다 보면 나중에 기억이 안 나서 못쓰는 경우가 생기더라고요.  발생할 때마다 기록으로 남기는 게 좋은 코딩 습관입니다. 전 그러지 못했지만요 ㅎㅎㅎ

제 에러 케이스가 도움이 됐길 바랍니다.

모두 즐코딩하시고 감사합니다.  ^___^

 

참고

https://v3.router.vuejs.org/kr/

https://router.vuejs.kr/

반응형

'IT > 개발' 카테고리의 다른 글

[NPM] Axios Error  (38) 2024.04.23
[Js, Vue] AbortController + onMounted + onUnMounted  (100) 2024.04.22
[Angular] HttpClient  (75) 2024.04.16
[Vite] vite로 번들링 도구를 바꾸기  (81) 2024.04.14
[Angular] standalone 적용하기  (58) 2024.04.13