[Vue] #13. 라우팅(Routing): SPA구축

bien·2024년 4월 8일
1

vue

목록 보기
11/11

개념 및 사용 목적

네비게이션 상 2개의 링크 (Teams, Users)가 존재한다 하자.
그러나 네비게이션의 링크를 클릭하면 화면에 표시되는 스크린은 바뀌지만, URL은 바뀌지 않는다.

Vue를 이용해서 Javascript 기반 클라이언트 사이드 웹 애플리케이션을 구축할 수 있는데, 이때 사용자는 브라우저에서 실행되는 JavaScript가 제어하는 것만 볼 수 있다. (이것이 Vue의 역할이기도 하다.)

또한, 애플리케이션이 패칭되는 단일 HTML 파일에 작성하는 모든 JavaScript 코드 스크립트가 import 되어있는 싱글 페이지 애플리케이션(SPA)를 구축하고 있다. 단순히 teams, users 폴더에 작성한 코드가 아니라, 해당 코드에 대한 변형 및 최적화 버전 코드가 포함된다. 이는 CLI가 모든 것을 백그라운드에 관리하기에 가능한 일이다. 결국, 하나의 HTML을 가지고 JavaScript 코드가 브라우저에서 실행되는, 화면에 표시되는 모든 것을 관장한다. 그러나 이 방식에는 바로 연상되는 하나의 문제점이 있는데, 페이지의 모든 영역에 있어 동일한 URL을 사용한다는 것이다.

만약 내가 www.도메인.com라는 주소를 타인과 공유하더라도, 이는 시작 페이지만 공유 가능함을 의미한다. 버튼을 클릭하면 페이지가 달라지는 것은 JavaScript 기반 동작으로 URL과 아무런 관련이 없기 때문이다.

URL의 변화 없이 JavaScript 코드 만으로 잘 작동하는 애플리케이션을 개발하더라도, 동시에 URL과 대화하는(interact) 상태여야만 위치한 페이지를 나타내는 URL을 다른 사용자와 공유할 수 있다.

🧐 그냥 여러 HTML 파일을 만들어서 서로 가르키도록 하면 안되나? www.도메인.com/Users.html처럼

Vue 애플리케이션을 그런식으로 구축하는 것은 의미가 없다. 각 HTML파일이 각자 다른 스크립트 코드와 서로 관계가 없는 것으로 인식될테니까.

대신, 이런 문제를 해결하기 위해 Vue에서 Routing(라우팅)이라는 기능을 제공하고 있다.

라우팅(Routing)이란?

  • 동일한 싱글페이지 애플리케이션 상에 URL이 변경되거나 해당 URL을 기반으로 화면에 이를 로드한다.
  • 반대로, 에플리케이션이 다른 위치로 이동할때 url이 해당 위치를 반영할 수 있다.
  • 동일한 패키지를 이용해 URL을 변경할 수도 있다.

라우팅에 대해 자세히 알아보자!


라우팅 설정

vue-router 설치

npm install --save vue-router

애플리케이션에 라우팅 등록

router.js 파일을 추가하는것 외에도, main.js에 router를 사용할 것을 알려줘야 한다.

main.js

import { createApp } from 'vue';
import { createRouter, createWebHistory } from 'vue-router';

import App from './App.vue';

const router = createRouter ({
	history: createWebHistory(),
    routes: []
});

cons tapp = createApp(App)

app.mount('#app');
  • import { createRouter, createWebHistory } from 'vue-router';

    • 설치한 패키지(vue-router)로부터 createRoute, createWebHistory 함수를 불러온다.
  • const router = createRouter ({history: , routes: []});

    • createRouter함수를 호출하여, 상수 router에 결괏값을 저장한다.
    • craeteRouter함수에 라우터 생성을 위해 JavaScript 객체를 입력한다.
      • 옵션 1. routes: 지원하고자 하는 URL 등록(배열을 통해)
      • 옵션 2. history: 라우터에게 히스토리 관리 방법을 알려준다.
  • history: createWebHistory()

    • 과거에는 브라우저 히스토리 확인을 위해 메모리를 조작하는 것이 가능하지 않았다. 따라서 라우터가 이 동작을 emulate해야 했다.
    • 그러나 이제는 createWebHistory 사용에 문제가 없어 이를 이용하고 있다.
    • 이 코드를 통해 라우터에게 내장 브라우저 지원 기능을 사용하라고 지정하고 있다.

라우팅 등록 및 렌더링

1. url & 컴포넌트 매핑

main.js

import { createApp } from 'vue';
import { createRouter, createWebHistory } from 'vue-router';

import App from './App.vue';
import TeamsList from './components/teams/TeamsList.vue';
import UsersList from './components/users/UsersList.vue';

const router = createRouter ({
	history: createWebHistory(),
    routes: [
    	{ path: '/teams', component: TemasList },
        	// 도메인.com/temas => TeamsList 컴포넌트
        { paht: '/users', component: UsersList },
        	// 도메인.com/users => UsersList 컴포넌트
    ]
});

cons tapp = createApp(App)

app.mount('#app');

2. vue에 route 상수 등록

app.use(router);
  • use(): vue 내장 메서드.
    • 서드 파티 패키지와 다른 기능을 연결해주는 역할을 수행한다.

3. 컴포넌트 랜더링 위치 알리기

이전 TheNavigation.vue

<template>
  <header>
    <nav>
      <ul>
        <li>
          <button @click="setActivePage('teams-list')">Teams</button>
        </li>
        <li>
          <button @click="setActivePage('users-list')">Users</button>
        </li>
      </ul>
    </nav>
  </header>
</template>

router-link를 적용한 TheNavigation.vue

<template>
  <header>
    <nav>
      <ul>
        <li>
          <router-link to="/teams">Teams</router-link>
        </li>
        <li>
          <router-link to="/users">Users</router-link>
        </li>
      </ul>
    </nav>
  </header>
</template>
  • <router-link to="/이동할경로">
    • vue 라우터에게 렌더링 위치를 알려주는 특수한 컴포넌트
    • 이 태그의 위치에 선택된 컴포넌트가 랜더링 된다.
    • 기술적으로 태그 내부에 슬롯을 사용하기 때문에 HTML 요소를 전달할 수도 있다.
    • to 프로퍼티: 이동할 경로를 문자열로 가진다.
  • 내부적으로 앵커 태그<a>를 랜더링한다.
    • 따라서, CSS 설정은 <a>태그에 적용해주면 된다. (위의 예시에서는 <button>에 적용되던 css를 <a/>태그로 옮겨주면 된다.)

Q. <a></a>태그와 유사해 보이는데, 어떤 차이점이 있나요?
A. 다른 페이지를 불러와 전체 새로고침하여 현재 상태를 잃는 앵커 태그 <a/>와 다르게, <router-link/>는 다른 페이지로 로드되는 것을 막고 사용자가 클릭한 링크를 분석하여 알맞은 컴포넌트를 로드하며 URL을 업데이트 합니다.


활성 링크 스타일링하기

TheNavigation.vue

button:hover,
button:active
a.router-link-active {
  color: #f1a80a;
  border-color: #f1a80a;
  background-color: #1a037e;
}

이후에 배우게 될 '중첩 라우팅' 사용 시, 두 속성을 구분해서 적용할 수 있다.

  • 현재 경로와 완벽하게 일치하는 내비게이션 항목에만 적용된다.
  • 현재 활성화된 라우트의 일부만 포함하는 네비게이션 항목에도 적용된다.

프로그래밍 방식 내비게이션

아래와 같은 요구사항이 있다고 생각해보자.

Confirm이란 버튼이 있고, 해당 버튼을 클릭하면 사용자 정보를 저장한다. 이후 'Users' 페이지로 이동한다.

위 요구사항에선 '양식 제출'이라는 특정 작업을 수행하고, 수행 이후 사용자를 다른 곳으로 이동시켜야 한다. 실제로 개발 상황에 빈번하게 요구될 수 있는 사항이다. 이를 구현하기 위해서 router를 어떻게 적용해야 할까?

1. 버튼 생성

<template>
	<button @click="confirmInput">Confirm<button>
    <ul>
    	<user-item v-for="user in users" :key="user.id" />
    </ul>
</template>

특정 작업을 수행해야 하므로, <router-link/> 태그를 사용하지 못하고, <button/>을 통해 confrimInput 메서드를 트리깅하고 있다.

2. 양식 제출을 실행할 메서드 구현

<script>
input UserItem from './UserItem.vue';

export default {
	components: {
    	UserItem,
    },
	inject: ['users'],
    methods: {
    	confirmInput() {
        	// 양식 제출 코드
			// 양식 제출 이후 다른 페이지로 이동!
		}
	}
</script>

3. 메서드 실행 후 다른 페이지로 이동.

<script>
//...
    methods: {
    	confirmInput() {
        	// 양식 제출 코드
            this.$router.push('/teams');
            this.$router.forward();	 // 앞으로 가기
            this.$router.back();	// 뒤로 가기
		}
	}
</script>

$router

  • this키워드로 접근 가능
  • push 메서드를 통해 라우팅 히스토리에 새 라우트(이동할 경로)를 추가(푸시)할 수 있다.

📌 결론

이동 전 실행해야 할 로직(코드)가 있는 경우 $router를 통해 이동하자!


라우트 매개변수를 사용하여 데이터 전달하기(동적 세그먼트)

main.js

// ...
const router = createRouter ({
	history: createWebHistory(),
    routes: [
    	{ path: '/teams', component: TeamsList },
        { paht: '/users', component: UsersList },   
    ]
});
// ...

아래와 같은 요구사항이 있다고 생각해보자.

경로가 '/teams/t1'이면 팀1 사람들의 정보를 보여주고, '/teams/t2'이면 팀2 사람들의 정보를 보여주고 싶어.

위 요구사항에 따르면, t1, t2와 같은 매개변수를 통해 다른 데이터를 컴포넌트에 로드해야 하는 상황이다. 즉, 라우트 매개변수가 있는 동적 라우트가 필요하다.

동적 매개변수 ('/콜론(:)+변수명')

    routes: [
        { path: '/teams/new' }    
        { path: '/teams/:teamId', component: TeamMembers }
    ]
  • { path: '/teams/:teamId'}
    • url 입력에 /teams 뒤에 /무언가를 입력하면 이 라우트가 활성화된다.

cf. { path: '/teams/new' }
new라는 하위 경로가 있는 경우, 순서가 동적 매개변수를 사용하는 경로보다 코드상 위에 위치해야 한다. 더 아래에 있는 경우, new는 매개변수 취급되어 해당 경로가 활성화되지 않게 된다. (new도 teamId로 취급하게 되는 것)

$route

	export default {
    	create() {
        	const teamId = this.$route.params.teamId;
        }
	}
  • this.$route.params.teamId;
    • 페이지 로드에 사용된 모든 매개변수를 갖고 있다.

내비게이션 및 동적 경로

TeamItem.vue

<template>
	<li>
    	<h3> {{ name }} </h3>
        <div class="team-member"> {{ memberCount }} Members </div>
        <router-link :to="'/teams/' + id"> View Members <router-link>
    </li>
</template>

<script>
export default {
	props: ['id', 'name', 'memberCount'],
};
</script>

<a href="">를 이용한 url의 변화가 아닌 라우트 링크를 통해서도 새로운 경로로 이동할 수 있다.

앞서 확인했던 <router-link to="/이동할경로">는 정적인 링크 생성을 위해 사용된다. 그러나 v-bind를 to 앞에 붙여주어 동적으로 변하는 링크를 생성할 수 있다.

이제 TeamItem.vue 컴포넌트마다 부모로 부터 전달받은(props를 통해) id에 따른 링크를 동적으로 생성할 것이다.

연산(computed) 활용하기

<template>의 로직을 줄여주기 위해 해당 코드를 연산(Computed) 프로퍼티에 옮길수도 있다.

TeamItem.vue

<template>
	<li>
    	<h3> {{ name }} </h3>
        <div class="team-member"> {{ memberCount }} Members </div>
        <router-link :to=teamMembersLink> View Members <router-link>
    </li>
</template>

<script>
export default {
	props: ['id', 'name', 'memberCount'],
    computed: {
    	teamMembersLink() {
        	return '/teams/' + this.id;
        }
};
</script>

매개변수 데이터 업데이트: 감시자(Watcher)를 통해

기존코드

export default {
	// ...
    created() {
    	const teamId = this.$route.params.teamId;
        const this.members = 팀원 호출 로직(teamId);
    },
}

🛑 문제상황

동적 매개변수로 로드된 페이지에서 다른 값을 가진 페이지로 간다면 화면이 업로드 되지 않는다.

/teams/t1/teams/t2로 이동하는 버튼이 있다. (매개변수의 값이 변한 상황) 이 버튼을 클릭하면 URL은 바뀌지만 화면에 표시되는 데이터는 변하지 않는다.

🔎 문제 원인

이는 페이지 탐색 시 Vue 라우터가 로드된 컴포넌트를 파기하고 새로 구축하지 않기 때문에 발생한다. Vue 라우터는 URL이 바뀔때마다 새롭게 컴포넌트를 만들지 않고 캐시에 저장해두고 사용한다.

즉, create()의 호출로 컴포넌트가 생성된(created) 이후 URL이 변경된다고 해서 컴포넌트를 파기하고 다시 created()를 실행하여 컴포넌트를 생성하지 않는다.

따라서 새로운 매개변수를 통해 다른 데이터를 가진 페이지를 로드하고 싶어도 Vue 라우터는 기본 설정상 반응하지 않는다.

어떻게 반응하도록 고칠 수 있을까?

🔨 해결방법: watch를 통해

$route의 변화

URL 변화 시 $route 프로퍼티도 변한다. 로드한 라우트에 대한 최신 정보를 담고 있으므로 URL 변경시 최신 매개변수로 업데이트된다.

따라서 감시자(Watcher)를 추가하여 내장 프로퍼티인 $route의 변화를추적할 수 있다.

export default {
	// ...
	methods: {
    	loadTeamMember() {
        	const teamId = this.$route.params.teamId;
            // teamLoading 로직
        }
    },
	created() {
		this.loadTeamMembers();
    },
    watch: {
    	$route() {
        	this.loadTeamMembers();
        }
	}        

기존에 라우트로부터 '팀ID'를 찾아 팀 정보를 로딩하는 로직을 loadTeamMember()로 메서드화 했다. 그리고 이 메서드를 created()watch에서 호출함으로써 컴포넌트 생성될 때만이 아니라, 라우터 정보가 바뀌었을 때에도 팀 정보 로딩을 실행하여 업데이트할 수 있다.

route 인수 전달

loadTeamMember()에서 직접 this.$route에서 인수를 조회하는 대신에, created()watch에서 인수를 전달하도록 수정한다.

export default {
	// ...
	methods: {
    	loadTeamMember(route) {
        	const teamId = route.params.teamId;
            // teamLoading 로직
        }
    },
	created() {
		this.loadTeamMembers(this.$route);
    },
    watch: {
    	$route(newRoute) {
        	this.loadTeamMembers(newRoute);
        }
	}        
  • created()

    • $route를 전달한다.
  • watch

    • route의 정보 변화를 추적하고, 새롭게 변한 route를 전달한다.

매개변수를 프로퍼티로 전달하기

🛑 문제상황: 라우터 의존

이전 코드

export default {
	// ...
	methods: {
    	loadTeamMember(route) {
        	const teamId = route.params.teamId;
            // teamLoading 로직 (teamId를 통해)
        }
    },
	created() {
		this.loadTeamMembers(this.$route);
    },
    watch: {
    	$route(newRoute) {
        	this.loadTeamMembers(newRoute);
        }
	}        

코드상 팀 정보를 로드하기 위해 필요한 정보를 라우트를 의존 ($route의 param 메서드를 통해 호출)하고 있다.

Vue 라우팅을 사용하면 URL을 기반으로 한 경로에 따라 컴포넌트가 로드되고, $route를 이용해 라우팅된 정보를 활용한다. 그러나 이같은 접근 방식은 다른 컴포넌트나 템플릿에서 TeamMembers.vue를 포함하고자 할 때 제한적일 수 있다.

예를 들어, 라우팅 하지 않고 다른 컴포넌트에 포함하거나, 한 번은 라우팅을 통하고 다른 한번은 템플릿의 태그를 통해 로드해서 다른 위치에서 사용하고 싶은 경우 문제가 될 수 있다. (라우트를 사용하지 않는 다른 방식에서 문제가 발생한다.)

🔨 해결방법: props를 통해

이같은 라우트 의존 문제는 로드할 때 프로퍼티(prop)을 활용하는 방법으로 해결할 수 있다. 즉, teamId를 프로퍼티로 가지고, 이 데이터가 필요한 곳에 this.$route대신 해당 프로퍼티를 참조하는 것이다.

route를 props로 대체

기존에 라우터를 통해 호출되던 teamId를 props의 teamId로 변경한다.

<script>
export default {
    props: ['teamId'],
   	methods: {
    	loadTeamMember(teamId) {
        	const teamId =
            // teamLoading 로직 (teamId를 통해)
        }
    },
	created() {
		this.loadTeamMembers(this.teamId);
    },
    watch: {
    	teamId(newId) {
        	this.loadTeamMembers(newId);
        }
	}        

route에 props옵션 추가

라우트는 기본 설정상 데이터를 프로퍼티에 업로드하지 않는다. Vue 라우터에 변수가 $route에만 전달되는 것이 아니라 프로퍼티로서 컴포넌트에 전달되어야 한다고 알려줘야 한다.

const router = createRouter({
	history: createWebHistory(),
    routes: [
    	{ path: '/teams', component: TeamList },
        { path: '/users', component: UserList },
    	{ path: '/teams/:teamId', component: TeamMembers, props: true },    
    ],
});    
  • props: true
    • URL의 정보가 컴포넌트 로드 시 프로퍼티로 전달된다.
    • 관련 프로퍼티만 전달된다면 라우팅이 아니어도 사용할 수 있어 활용성이 높아진다!

redirect 및 "Catch All" 라우트

/route/index.js

const router = createRouter({
	history: createWebHistory(),
    routes: [
    	{ path: '/teams', component: TeamList },
        { path: '/users', component: UserList },
    	{ path: '/teams/:teamId', component: TeamMembers, props: true },    
    ],
});    

일반적으로 사용자는 도메인주소만을 가지고 사이트에 접속한다. (예를 들어, 네이버에 접속할 경우 www.naver.com으로 사이트에 접속할 것이다.) 이 경우 라우터는 경로(path)가 /인 라우트를 찾는다. 그러나 route의 경로 중 '/'와 일치하는 경로가 없기 때문에 화면을 로드하지 못한다. 이 문제를 해결하기 위해서는 라우트에 / 경로를 추가해줘야 한다.

/route/index.js

const router = createRouter({
	history: createWebHistory(),
    routes: [
    	{ path: '/', component: TeamList },
    	{ path: '/teams', component: TeamList },
        { path: '/users', component: UserList },
    	{ path: '/teams/:teamId', component: TeamMembers, props: true },
    ],
});    
  • { path: '/', component: TeamList },
    • 기본 접속 페이지로 TeamList 컴포넌트를 제공하고 싶어 새로운 경로로 해당 컴포넌트를 연결해주었다.

만약 단순히 TeamList 컴포넌트를 보여주는 것 뿐만이 아니라 주소자체를 도메인주소/teams로 변경하고 싶으면 어떻게 해야할까?
이럴때 redirect 혹은 alias 프로퍼티를 활용할 수 있다.

redirect

    routes: [
    	{ path: '/', redirect: '/teams' },
    	{ path: '/teams', component: TeamList },
	],
  • 도메인으로 접속하더라도 도메인/teams로 URL이 변경된다.
  • Vue 라우터에 의해 팀 목록이 뜨는 페이지로 리디렉션된다. (다른 경로로 이동한다.)

alias (별칭)

    routes: [
    	{ path: '/teams', component: TeamList, alias: '/' },
        { path: '/users', component: UserList },
    	{ path: '/teams/:teamId', component: TeamMembers, props: true },
    ],
  • /teams 경로에 /라는 별칭을 부여한다.
  • URL이 변경되지 않는다. (다른 경로로 이동하지 않는다. 다른 라우트에서 같은 컴포넌트를 로드한다.)

catchAll

지원하지 않는 라우트 접속

사용자가 지원하지 않는 라우트를 접속하는 경우 (ex. route에 없는 localhost:8080/something으로 접속하는 경우) 사용자가 입력 가능한 모든 URL에 라우트를 지정할 순 없다. 이럴 때 catchAll 라우트를 사용할 수 있다.

const router = createRouter({
	history: createWebHistory(),
    routes: [
    	{ path: '/', component: TeamList },
    	{ path: '/teams', component: TeamList },
        { path: '/users', component: UserList },
    	{ path: '/teams/:teamId', component: TeamMembers, props: true },
        { path: '/:notFound(.*)', component: NotFound },
    ],
});    
  • path: '/:notFound(.*)', component: NotFound
    • 우선순위가 가장 낮으므로 반드시 모든 라우트의 하단에 위치해야 한다. (상단의 모든 라우트가 처리하지 못하는 경우에만 해당 라우트가 적용되도록)
    • 동적 세그먼트(/:)로 /경로 뒤 무언가 특정 값이(notFound에 해당하는) 입력되는 경우를 지정한다.
    • (.*): Vue라우터가 지원하는 정규 표현식. notFound위치에 어떠 ㄴ값이든 모두 올 수 있음을 의미.
    • 메인페이지로 이동하는 링크를 가진 NotFound.vue 컴포넌트를 연결할 수 있다.
  • path: '/:notFound(.*)', redirect: '/teams'
    • 바로 메인페이지로 리디렉션 할 수도 있다.

중첩 라우트 사용하기

라우터 안에 또 다른 라우터를 설정하고 싶은 경우 중첩 라우팅을 통해 구현할 수 있다.

const router = createRouter({
	history: createWebHistory(),
    routes: [
    	{ path: '/', component: TeamList },
    	{ path: '/teams', component: TeamList },
        { path: '/users', component: UserList },
    	{ path: '/teams/:teamId', component: TeamMembers, props: true },
        { path: '/:notFound(.*)', component: NotFound },
    ],
});    

현재의 router.js에서는 모든 라우트들이 루트 레벨에 속해 서로 형제 관계이다. 중첩 라우트 구성은 내부에 라우트를 중첩하려는 라우트로 이동하여 children 옵션을 추가하는 방법으로 설정한다.

/temas라우트는 /teams/:teamId라우트를 취하게 되므로 /teams 라우트의 children으로 포함시킬 수 있다.

const router = createRouter({
	history: createWebHistory(),
    routes: [
    	{ path: '/', component: TeamList },
    	{ 
        	path: '/teams', 
            component: TeamList
            children: [
            	{ path: ':teamId', component: TeamMembers, props: true }
            ]
        },
        { path: '/users', component: UserList },
        { path: '/:notFound(.*)', component: NotFound },
    ],
});    

1. children 옵션 추가

    	{ 
        	path: '/teams', 
            component: TeamList
            children: [
            	{ path: ':teamId', component: TeamMembers, props: true }
            ]
        },
  • 부모가 가지는 '/teams' 경로는 중복작성하지 않아도 괜찮다.
  • 자식 라우트로 다른 경로를 추가 작성할 수 있다.

2. 부모 컴포넌트에 router-view 추가하기

App.vue 파일에 사용한 router-view 컴포넌트는 앱 전체에 사용되는 최상단 컴포넌트로 오직 루트 라우트(routes 배열에 직접 등록한 라우트)만 다룬다. 따라서 자식 라우트는 router-view에 렌더링되지 않는다. 대신 children을 가지는 부모 컴포넌트에 router-view 를 추가해줘야 한다.(이 경우 TeamList)

TeamList.vue

<template>
	<router-view></router-view>
    <ul>
    	<teams-item
        	v-for="team in teams"
            :key="team.id"
            :id="team.id"
            //...
        ></teams-item>
    </ul>
</template>

부모 컴포넌트에 추가된 <router-view>부분에 자식 컴포넌트들이 렌더링되게 된다.

3. Css: active

Vue Router에서는 'router-link' 요소의 활성 상태를 나타내기 위해 router-link-activerouter-link-exact-active 클래스를 제공한다.

  • router-link-active 클래스: 현재 URL이 링크의 'to' 속성과 일치하면 적용된다.
  • router-link-exact-active 클래스: 현재 URL이 링크의 'to'속성과 정확하게 일치하면 적용된다.

만약 아래와 같은 Vue 템플릿과 Css 설정이 있다고 생각해보자.

<router-link to="/teams" class="my-link" exact>Teams</router-link>
.router-link-active {
  font-weight: bold;
}

.router-link-exact-active {
  color: #ff0000; /* 빨간색으로 변경 예시 */
}
  • router-link-exact-active css 속성인 경우, 정확히 경로가 /teams인 경우에만 해당 클래스의 css 설정이 적용된다.
  • router-link-active css 속성인 경우, /temas/123과 같이루트 경로가 일치하는 경우 해당 css가 적용된다.

따라서, 중첩 라우트 구성의 경우 router-link-active의 css가 적용되게 된다.


이름이 있는 라우트 및 위치 객체 더 알아보기

규모가 큰 Vue 애플리케이션의 경우 수십, 수백개의 다양한 라우트와 중첩 라우트가 있을 수 있다. 중첩 라우트를 여러 레벨로 나누고, 그 중첩 라우트에 또 자식 라우트를 만들 수 있으니 링크를 생성하는 것이 매우 복잡해질 수 있다.

<router-link :to="teamMembersLink"> View Members </router-link>

computed: {
	teamMemberLink() {
    	return '/teams/' + this.id;
	}
}

항상 위와 같이 이동할 모든 경로를 문자열로 조합하는 것은 번거롭고 어려운 일이다. 이런 경우를 위해 Vue는 경로 이동에 유용한 기능을 제공하고 있다.

1. to 프로퍼티에 객체 전달하기

router-link 요소에 적용되는 to 프로퍼티는 (경로를 다루는) 문자열 링크뿐만 아니라 객체를 사용할 수도 있다. 이 경우 반드시 to 프로퍼티와 :을 동적으로 바인딩해야 한다. (<router-link :to=>)

computed: {
	teamMemberLink() {
    	return { path: '/teams' + this.id };
	}
}

문자열 대신 객체를 전달했다. 하지만 이는 객체 내부에 작성했을 뿐 앞서 작성한 것과 별반 다를 것이 없다.

2. Named Routes(기명 라우트)

라우트 구성에 name 프로퍼티를 추가함으로써 작성한 모든 라우트에 이름을 할당할 수 있다.

routes: [
  {
  	name: 'teams',
    path: '/teams',
    component: TeamsList,
    children: [
      {name: 'team-members', path: 'teamId', component: TeamMembers, props: True }
    ]
  ],

profile
Good Luck!

0개의 댓글