관리 메뉴

열심히 일한 당신 떠나라

코딩 자율학습단(Vue.js 프런트엔드 개발 입문) 13일차 본문

정보교육/프런트엔드

코딩 자율학습단(Vue.js 프런트엔드 개발 입문) 13일차

@thiskorea 2024. 7. 3. 14:40

[Vue 13일차]
 ~8.3 뷰 라우터의 고급 기능 다루기
(종이책 p.374-390)

내비게이션 가드

라우팅 과정 중 특정 지점에서 라우트 전환을 가로채 사용자 정의 로직을 실행할 수 있게 해주는 훅

내비게이션 가드를 사용하며 라우트 접근을 제어하거나 조건에 따른 다른 라우트로 리다이렉션하거나 라우트 변경 전에 데이터를 불러오는 작업 등을 수행할 수 있다.

사용방식에 따라 전역 가드, 라우트별 가드, 컴포넌트 내 가드로 구분할 수 있다.

경로 메타 필드

meta 속성을 사용해 해당 라우트에 대한 추가적인 사용자 정의 정보를 저장하는 기능 제공

// src/router/index.js

import { createRouter, createWebHistory } from "vue-router";
import HomeView from "@/views/HomeView.vue";
import UserView from "@/views/UserView.vue";

const router = createRouter({
    history: createWebHistory(),
    routes: [
        {
            path: '',
            name: 'home',
            component: HomeView,
            meta: {
                title: 'Home',
            },
        },
        {
            path: '/about',
            name: 'about',
            component: () => import('../views/AboutView.vue'),
            meta: {
                title: 'About',
            },
        },
        {
            path: '/:user/:id',
            name: 'user',
            component: UserView
        }
    ],
});

router.beforeEach((to, from, next) => {
    if (to.meta.title) {
        document.title = to.meta.title;
    }
    next();
});

export default router;

스크롤 동작

// src/router/index.js

import { createRouter, createWebHistory } from "vue-router";
import HomeView from "@/views/HomeView.vue";
import UserView from "@/views/UserView.vue";

const router = createRouter({
    history: createWebHistory(),
    routes: [
        {
            path: '',
            name: 'home',
            component: HomeView,
            meta: {
                title: 'Home',
            },
        },
        {
            path: '/about',
            name: 'about',
            component: () => import('../views/AboutView.vue'),
            meta: {
                title: 'About',
            },
        },
        {
            path: '/:user/:id',
            name: 'user',
            component: UserView
        }
    ],
    scrollBehavior(to, from, savedPosition) {
        // 스크롤 위치를 저장했다면, 그 위치로 스크롤합니다.
        if (savedPosition) {
            return savedPosition;
        } else {
            // 새로운 라우트로 이동하면 맨 위로 스크롤합니다.
            return { top: 0 };
        }
    }
});

router.beforeEach((to, from, next) => {
    if (to.meta.title) {
        document.title = to.meta.title;
    }
    next();
});

export default router;
// src/App.vue

<template>
  <div id="app" @wheel="handleScroll">
    <nav>
      <ul>
        <li><router-link to="/">Home</router-link></li>
        <li><router-link to="/about">About</router-link></li>
      </ul>
    </nav>
    <router-view />
  </div>
</template>

<script>
export default {
  name: 'App',
  data() {
    return {
      lastScrollTop: 0,
      ticking: false
    };
  },
  methods: {
    handleScroll(event) {
      const delta = event.deltaY;
      if (!this.ticking) {
        window.requestAnimationFrame(() => {
          if (delta > 0) {
            // 스크롤 다운
            if (this.$route.name === 'home') {
              this.$router.push({ name: 'about' });
            }
          } else {
            // 스크롤 업
            if (this.$route.name === 'about') {
              this.$router.push({ name: 'home' });
            }
          }
          this.ticking = false;
        });
        this.ticking = true;
      }
    }
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
  height: 100vh;
  overflow: hidden;
}

nav ul {
  list-style-type: none;
  padding: 0;
}

nav li {
  display: inline;
  margin-right: 10px;
}
</style>