ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 코딩 자율학습단(Vue.js 프런트엔드 개발 입문) 13일차
    정보교육/프런트엔드 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>

     

Designed by Tistory.