vue.js를 이용한 이력서 만들기 (1)

고태경·2024년 10월 26일
0

  1. 프로젝트 생성
  2. 타이핑 효과 구현
  3. 스크롤에 따른 헤더
  4. 폰트 어썸으로 아이콘 추가

1. vue js 프로젝트 생성

# 터미널에 입력
vue create front-end-resume
Vue CLI v5.0.8
? Please pick a preset: Default ([Vue 3] babel, eslint)
? Pick the package manager to use when installing dependencies: Yarn

-> 이런 거 뜨면 enter 입력
  1. 프로젝트 실행 (프로젝트 경로에서 입력)
# 내 경우 
# /Users/gotaegyeong/Library/CloudStorage/OneDrive-인하공업전문대학/대학교/3학년\ 2학기/front-end\ 실습/front_end_project/front-end-resume
npm run serve

2. 타이핑 효과 구현

에러 및 해결 - vue 버전 문제

Vue.directiveundefined로 평가되기 때문에 발생하는 것
이는 Vue 3를 사용하는 경우 발생할 수 있으며, Vue 3에서는 Vue.directive 방식이 아닌 Composition API를 사용하는 방식으로 디렉티브를 정의해야 함

vue 3 인지 보는 법

package.json에서 dependencies 부분 확인

  "dependencies": {
    "core-js": "^3.8.3",
    "vue": "^3.2.13"
  },

변경 전

// main.js
import Vue from 'vue'
import App from './App.vue'
import typingEffect from './directives/typingEffect'

Vue.directive('typing', typingEffect)

new Vue({
    render: h => h(App),
}).$mount('#app')

변경 후 (전역 디렉티브를 Vue 3 방식으로 등록)

// main.js
import { createApp } from 'vue'
import App from './App.vue'
import typingEffect from './directives/typingEffect'

const app = createApp(App)
app.directive('typing', typingEffect)
app.mount('#app')

변경 전

// typingEffect.js
export default {
    inserted: function (el, binding) {
        let text = binding.value;
        let delay = el.dataset.delay;
        let index = 0;
        el.innerHTML = '';

        function typeWriter() {
            if (index < text.length) {
                el.innerHTML += text.charAt(index);
                index++;
                setTimeout(typeWriter, delay);
            }
        }

        typeWriter();
    }
};

변경 후 (Vue 3에서 사용할 수 있도록 inserted 대신 mounted 훅을 사용)

// TypingEffect.js
export default {
    mounted(el, binding) {
        let text = binding.value;
        let delay = el.dataset.delay;
        let index = 0;
        el.innerHTML = '';

        function typeWriter() {
            if (index < text.length) {
                el.innerHTML += text.charAt(index);
                index++;
                setTimeout(typeWriter, delay);
            }
        }

        typeWriter();
    }
};

App.vue

변경 전

<template>
  <div>
    <h1 v-typing.data-delay="2000">Hello, World!</h1>
  </div>
</template>

<script>
export default {
  name: 'App',
  directives: {
    typing: {
      inserted: function (el, binding) {
        let text = binding.value;
        let delay = el.dataset.delay;
        let index = 0;
        el.innerHTML = '';

        function typeWriter() {
          if (index < text.length) {
            el.innerHTML += text.charAt(index);
            index++;
            setTimeout(typeWriter, delay);
          }
        }

        typeWriter();
      }
    }
  }
}
</script>

변경 후
(디렉티브에서 mounted 훅 사용: Vue 3에서는 inserted가 아니라 mounted를 사용해야 함
binding.value 전달: v-typing 디렉티브에 값을 직접 전달)

<template>
 <div>
   <!-- 디렉티브에 문자열 값을 직접 전달합니다 -->
   <h1 v-typing="'Hello, World!'" data-delay="200">Hello, World!</h1>
 </div>
</template>

<script>
export default {
 name: 'App',
 directives: {
   typing: {
     mounted(el, binding) {  // Vue 3에서는 mounted 사용
       let text = binding.value;  // 전달된 텍스트 값
       let delay = parseInt(el.dataset.delay) || 100;  // 기본값을 100ms로 설정
       let index = 0;
       el.innerHTML = '';

       function typeWriter() {
         if (index < text.length) {
           el.innerHTML += text.charAt(index);
           index++;
           setTimeout(typeWriter, delay);
         }
       }

       typeWriter();
     }
   }
 }
}
</script>

3. 스크롤에 따른 헤더

  1. CSS 클래스 추가
    헤더가 숨겨질 때 적용될 scrollDown 클래스를 정의
    src/assets/styles.css에 추가
.scrollDown {
  transform: translateY(-100%); /* 헤더를 위로 숨기기 */
  transition: transform 0.3s ease; /* 부드러운 이동 효과 */
}
  1. App.vue 수정
<template>
  <div>
    <header :class="{ scrollDown: isScrollDown }">
      <!-- 헤더 내용 -->
      <h1>포트폴리오</h1>
    </header>
    <!-- 나머지 콘텐츠 -->
    <main>
      <p>여기에 포트폴리오 콘텐츠가 들어갑니다.</p>
    </main>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isScrollDown: false, // 스크롤 상태를 관리하는 변수
      prevScrollTop: 0
    };
  },
  mounted() {
    window.addEventListener("scroll", this.handleScroll);
  },
  beforeDestroy() {
    window.removeEventListener("scroll", this.handleScroll);
  },
  methods: {
    handleScroll() {
      const nextScrollTop = window.pageYOffset || 0;
      if (nextScrollTop > this.prevScrollTop) {
        // 스크롤 다운
        this.isScrollDown = true;
      } else if (nextScrollTop < this.prevScrollTop) {
        // 스크롤 업
        this.isScrollDown = false;
      }
      this.prevScrollTop = nextScrollTop;
    }
  }
};
</script>

4. 폰트어썸

  1. 라이브러리 설치
    npm 캐시 폴더(/Users/gotaegyeong/.npm)의 소유자를 현재 사용자로 변경
sudo chown -R $(whoami) /Users/gotaegyeong/.npm
npm i--save@fortawesome/fontawesome-svg-core 
npm i--save@fortawesome/vue-fontawesome 
npm i--save@fortawesome/free-solid-svg-icons 
npm i--save@fortawesome/free-regular-svg-icons 
npm i--save@fortawesome/free-brands-svg-icons
  1. main.js에 추가
import { library } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
import { fas } from '@fortawesome/free-solid-svg-icons';

// 아이콘 라이브러리에 'fas' 아이콘 추가
library.add(fas);

app.component('font-awesome-icon', FontAwesomeIcon);

참고 사이트

개발 환경 설정
https://jpointofviewntoe.tistory.com/63

타이핑 구현
https://www.php.cn/ko/faq/610527.html

스크롤에 따른 헤더 구현
https://cocoder16.tistory.com/47

profile
컴퓨터정보과

0개의 댓글

관련 채용 정보