본문 바로가기
Tutorial/port2023

24. 포트폴리오 사이트 만들기 : Vue-Site : 인트로 영역

by @webstoryboy 2023. 7. 31.
Tutorial/portfolio

포트폴리오 사이트 만들기 - Vue

by @webs 2023. 08. 01.
04
포트폴리오 사이트 만들기 : 인트로 영역
난이도 중간

소개

안녕하세요! 웹스토리보이입니다. 오늘은 인트로 컴퍼넌트를 작업해보겠습니다. 소스를 직접 치고 만드는 것이 아니라, 기존에 소스를 활용해서 만드는 것이기 때문에 비교적 빨리 만들 수 있을겁니다. 그럼 오늘도 시작해볼까요!! 🥶

포트폴리오 사이트 만들기

VITE SITE

  • 1. 셋팅하기
    • 1_1. vite 설치하기
    • 1_2. vite 폴더 정리하기
    • 1_3. gsap/lenis 설치하기
    • 1_4. git 연동하기
  • 2. 레이아웃
    • 2.1 레이아웃 구조 만들기
    • 2.2 메인 레이아웃 구조 만들기
    • 2.3 CSS 셋팅하기
    • 2.4 JavaScript 셋팅하기
  • 3. 헤더 영역
    • 3.1 헤더 구조 잡기
    • 3.2 헤더 디자인 설정
    • 3.3 반응형 작업하기
    • 3.4 메뉴 자바스크립트 설정
  • 4. 인트로 영역
    • 4.1 인트로 구조 잡기
    • 4.2 인트로 디자인 설정
    • 4.3 반응형 작업하기
  • 5. 스킬 영역
    • 5.1 스킬 구조 잡기
    • 5.2 스킬 디자인 설정
    • 5.3 반응형 작업하기
  • 6. 사이트 영역
    • 6.1 사이트 구조 잡기
    • 6.2 사이트 디자인 설정
    • 6.3 반응형 작업하기
  • 7. 포트폴리오 영역
    • 7.1 사이트 구조 잡기
    • 7.2 사이트 디자인 설정
    • 7.3 반응형 작업하기
    • 7.4 스크립트 작업하기
  • 8. 연락처 영역
    • 8.1 연락처 구조 잡기
    • 8.2 연락처 디자인 설정
    • 8.3 반응형 작업하기
  • 9. 푸터 영역
    • 9.1 푸터 구조 잡기
    • 9.2 푸터 디자인 설정
    • 9.3 반응형 작업하기
  • 10. 마무리
    • 10.1 스무스 효과주기
    • 10.2 링크 연결하기
    • 10.3 netlify에 배포하기

REACT SITE

  • 1. 셋팅하기
    • 1_1. React 설치하기
    • 1_2. React 폴더 정리하기
    • 1_3. 라이브러리 설치하기
    • 1_4. git 연동하기
  • 2. 라우팅 및 컴퍼넌트
    • 2_1. 라우팅 설정하기
    • 2_2. 컴퍼넌트 설정하기
    • 2_3. SCSS 설정하기
  • 3. 헤더 영역
    • 3_1. 헤더 구조잡기
    • 3_2. 헤더 디자인 설정
    • 3_3. 헤더 데이터 작업
    • 3_4. 헤더 토글 메뉴 작업하기
  • 4. 인트로 영역
    • 4_1. 인트로 구조잡기
    • 4_2. 인트로 디자인 설정
    • 4_3. 인트로 데이터 작업
  • 5. 스킬 영역
    • 5_1. 스킬 구조잡기
    • 5_2. 스킬 디자인 설정
    • 5_3. 스킬 데이터 작업
  • 6. 사이트 영역
    • 6_1. 사이트 구조잡기
    • 6_2. 사이트 디자인 설정
    • 6_3. 사이트 데이터 작업
  • 7. 포트폴리오 영역
    • 7_1. 포트폴리오 구조잡기
    • 7_2. 포트폴리오 디자인 설정
    • 7_3. 포트폴리오 데이터 작업
  • 8. 연락처 영역
    • 8_1. 연락처 구조잡기
    • 8_2. 연락처 디자인 설정
    • 8_3. 연락처 데이터 작업
  • 9. 푸터 영역
    • 9_1. 푸터 구조잡기
    • 9_2. 푸터 디자인 설정
    • 9_3. 푸터 데이터 작업
  • 10. 마무리
    • 10_1. 데이터 통합하기
    • 10_2. 스무스 효과 넣어주기
    • 10_3. 가로모드 구현하기
    • 10_4. netlify에 배포하기

VUE SITE

  • 1. 셋팅하기
    • 1_1. Vue 설치하기
    • 1_2. Vue 폴더 정리하기
    • 1_3. 라이브러리 설치하기
    • 1_4. git 연동하기
  • 2. 라우팅 및 컴퍼넌트
    • 2_1. 라우팅 설정하기
    • 2_2. 컴퍼넌트 설정하기
    • 2_3. SCSS 설정하기
  • 3. 헤더 영역
    • 3_1. 헤더 구조잡기
    • 3_2. 헤더 디자인 설정
    • 3_3. 헤더 데이터 작업
    • 3_4. 헤더 토글 메뉴 작업하기
  • 4. 인트로 영역
    • 4_1. 인트로 구조잡기
    • 4_2. 인트로 디자인 설정
    • 4_3. 인트로 데이터 작업

4. 인트로 영역

4.1 인트로 구조잡기

기본 코드부터 가져오겠습니다.

<template>
    <section id="intro">
        <div class="intro__inner">
            <h2 class="intro__title">
                port developer
            </h2>
            <div class="intro__lines" aria-hidden="true">
                <span class="line"></span>
                <span class="line"></span>
                <span class="line"></span>
                <span class="line"></span>
                <span class="line"></span>
                <span class="line"></span>
                <span class="line"></span>
            </div>
            <div class="intro__text">
                <div class="text">
                    <div>talent is</div>
                    <div>found at the end of the</div>
                    <div>effort</div>
                </div>
                <div class="img">
                    <img src="@assets/img/about.jpg" alt="어바웃" />
                </div>
            </div>
            <div class="intro__lines bottom" aria-hidden="true">
                <span class="line"></span>
                <span class="line"></span>
                <span class="line"></span>
                <span class="line"></span>
                <span class="line"></span>
                <span class="line"></span>
                <span class="line"></span>
            </div>
        </div>
    </section>
</template>

4.2 인트로 디자인 설정

CSS로 SCSS로 변형하여 작업하였습니다. lang="scss"는 scss를 쓰기 위한 표시이며, scoped 속성은 스타일이 컴포넌트에만 적용되도록 지정하는 것을 의미합니다. Vue의 Single File Component(SFC)에서는 기본적으로 스타일이 전역으로 적용되지만, scoped 속성을 추가하면 해당 컴포넌트에만 스타일이 적용되게 됩니다.

<style lang="scss" scoped>
    #intro {
        height: 100vh;
    }
    .intro__inner {
        width: 100%;
        height: 100%;
        display: flex;
        align-items: flex-start;
        justify-content: flex-end;
        flex-direction: column;
        padding: 16px;
    
        @media (max-width: 800px){
            justify-content: center;
        }
    
        .intro__title {
            font-size: 10vw;
            text-transform: uppercase;
            line-height: 1;
            font-weight: 800;
            white-space: nowrap;
            text-indent: -0.5vw;
            letter-spacing: -0.3vw;
    
            @media (max-width: 320px){ 
                display: none;
            }
        }
        .intro__text {
            width: 100%;
            height: 40vh;
            background-color: var(--black);
            color: var(--white);
            display: flex;
            align-items: center;
            justify-content: center;
            flex-direction: column;
            position: relative;
    
            .text {
                font-size: 3vw;
                line-height: 1;
                font-weight: 900;
                text-transform: uppercase;
                text-decoration: underline;
                text-align: center;
                position: relative;
                z-index: 100;
                transition: all 0.3s;
                cursor: all-scroll;
    
                @media (max-width: 800px){ 
                    font-size: 24px;
                }
            }
            .img {
                position: absolute;
                left: 50%;
                top: 50%;
                transform: translate(-50%, -50%);
                width: 30vh;
                height: 30vh;
                border-radius: 50%;
                overflow: hidden;
                filter: grayscale(100%);
                transition: all 0.3s;
    
                @media (max-width: 320px){ 
                    width: 20vh;
                    height: 20vh;
                }
            }
    
            &:hover .text {
                opacity: 0;
            }
            &:hover .img {
                filter: grayscale(0);
            }
        }
        .intro__lines {
            width: 100%;
    
            .line {
                display: block;
                width: 100%;
                height: 1px;
                background-color: var(--black);
                margin-bottom: 0.5vw;
    
                &:nth-child(1){
                    height: 1px;
                }
                &:nth-child(2){
                    height: 2px;
                }
                &:nth-child(3){
                    height: 5px;
                }
                &:nth-child(4){
                    height: 9px;
                }
                &:nth-child(5){
                    height: 13px;
                }
                &:nth-child(6){
                    height: 17px;
                }
                &:nth-child(7){
                    height: 25px;
                }
            }
    
            &.bottom {
                .line {
                    margin-top: 0.5vw;
                    margin-bottom: 0;
                    display: none;
    
                    @media (max-width: 800px){ 
                        display: block;
                    }
    
                    &:nth-child(1){
                        height: 25px;
                    }
                    &:nth-child(2){
                        height: 17px;
                    }
                    &:nth-child(3){
                        height: 13px;
                    }
                    &:nth-child(4){
                        height: 9px;
                    }
                    &:nth-child(5){
                        height: 5px;
                    }
                    &:nth-child(6){
                        height: 2px;
                    }
                    &:nth-child(7){
                        height: 1px;
                    }
                }
            }
        }
    }
</style>

4.3 인트로 데이터 작업

핵심 데이터는 따로 작업하였습니다.

export const introText = {
    title: "port developer",
    desc: ["talent is", "found at the end of the", "effort"],
};

데이터를 import 하고 해당 부분에는 {{}} 표시를 하고 데이터를 불러오면 됩니다.

<script setup>
import { introText } from "@/constants/index";
</script>

<template>
    <section id="intro">
        <div class="intro__inner">
            <h2 class="intro__title">
                {{ introText.title }}
            </h2>
            <div class="intro__lines" aria-hidden="true">
                <span class="line"></span>
                <span class="line"></span>
                <span class="line"></span>
                <span class="line"></span>
                <span class="line"></span>
                <span class="line"></span>
                <span class="line"></span>
            </div>
            <div class="intro__text">
                <div class="text">
                    <div>{{ introText.desc[0] }}</div>
                    <div>{{ introText.desc[1] }}</div>
                    <div>{{ introText.desc[2] }}</div>
                </div>
                <div class="img">
                    <img src="@/assets/img/about.jpg" alt="어바웃" />
                </div>
            </div>
            <div class="intro__lines bottom" aria-hidden="true">
                <span class="line"></span>
                <span class="line"></span>
                <span class="line"></span>
                <span class="line"></span>
                <span class="line"></span>
                <span class="line"></span>
                <span class="line"></span>
            </div>
        </div>
    </section>
</template>

3. 마무리

인트로 섹션이 완료가 되었습니다. 데이터 불러오는 부분이나 SCSS를 적용하는 방법은 기존과 결코 다르지 않습니다. 익숙함이 실력 향상의 기본입니다. 많이 해보고 많이 실패해봐야 좋은 사이트를 만들수 있습니다. 수고하셨습니다. 😳😳 깃헙에 올리는 것도 계속해주세요!!


예제 목록

댓글