Vue.js + Firebase를 사용하여 포트폴리오를 만들었습니다.

※ 본 투고는 TechCommit Advent Calendar 2019 11일째의 기사입니다.

소개



평상시는 Web제작회사에서 코더의 아르바이트를 하고 있는 대학 4회생입니다. 내정처의 회사에서 Vue.js를 사용하고 있다는 것도 있어, Vue.js로 간단하게 무엇인가 작성해 보려고 생각해 포트폴리오를 작성했습니다.

이번에는 Vue.js + Vuetify + Vue Router를 사용하여 SPA 포트폴리오를 만들고 Firebase에 호스팅했기 때문에 그 흐름 등에 대해 씁니다!

실제로 만든 포트폴리오
htps : // 흠뻑 빠지다 p. 이 m




환경


  • Vue CLI v4.1.1
  • Node.js v12.6.0
  • npm v6.9.0

  • 포트폴리오를 만들기 전에 생각한 것



    무엇을 게시할까


    
    - トップページ
    - 簡単な自己紹介
    - 作品
    - スキル
    - お問い合わせ
    

    대략 이런 느낌으로 구성하기로 했습니다.

    Vue.js에서 어떤 것을 만들 수 있는지 확인



    「Vue.js 포트폴리오」로 검색하면 많은 기사가 나오므로, 그것을 한번에 읽었습니다.

    도움이 된 기사
  • 프런트 미학습의 대학생이 1주일에 Vue.js를 사용한 포트폴리오를 만든 이야기
  • Vue를 배우고 SPA 대응 포트폴리오 사이트를 자작하기까지의 길
  • 【Vue.js 입문】독학 1주일에 SPA 대응의 간이 포트폴리오 사이트를 자작해 보았다!
  • Vue.js에서 드라쿠에 스타일의 포트폴리오를 만든 이야기
  • Vue.js + Firebase로 포트폴리오를 만드세요!
  • Vue.js + Firebase functions로 문의 양식 만들기

  • 디자인을 생각하다



    Cacoo 이라는 서비스를 사용하여 쉽게 와이어 프레임을 만들어 보았습니다.

    시트 6장까지는 무료로 사용할 수 있으므로 이번 작성하는 포트폴리오와 같이 페이지수가 적은 컨텐츠이면 무료 테두리라도 충분합니다.

    실제로 만든 간단한 와이어 프레임
    PC


    SP


    실장해 가면 「역시 여기를 이런 식으로 하고 싶다」라고 생각하기도 하고, 다소 변경했습니다.

    실제로 포트폴리오를 만듭니다.



    사양


  • 디자인은 Vuetify를 사용
  • SPA 구축 (Vue Router)
  • 텍스트 애니메이션
  • 모달 윈도우
  • 문의 양식 (Firebase Functions를 사용하여 메일 양식 작성)
  • 아이콘은 font-awesome을 사용

  • Vuetify + Vue Router


    vue add vuetify 에서 vuetify를 추가, 모드는 Default를 선택.
    Vue Router의 경우 vue create 때때로 Router를 선택하여 vue-router를 사용할 수 있도록했습니다.

    src/router/index.js
    import Vue from 'vue'
    import VueRouter from 'vue-router'
    import Top from '@/components/Top'
    import Profile from '@/components/Profile'
    import Work from '@/components/Work'
    import Skill from '@/components/Skill'
    import ContactForm from '@/components/ContactForm'
    
    Vue.use(VueRouter)
    
    const routes = [
      {
        path: '/',
        component: Top
      },
      {
        path: '/profile',
        component: Profile
      },
      {
        path: '/works',
        component: Work
      },
      {
        path: '/skills',
        component: Skill
      },
      {
        path: '/contact',
        component: ContactForm
      },
    ]
    
    const router = new VueRouter({
      mode: 'history',
      base: process.env.BASE_URL,
      routes
    })
    
    export default router
    
    

    src/main.js
    import Vue from 'vue'
    import App from './App.vue'
    import router from './router'
    import vuetify from './plugins/vuetify';
    import '@fortawesome/fontawesome-free/css/all.css'
    
    Vue.config.productionTip = false
    
    new Vue({
      router,
      vuetify,
      render: h => h(App)
    }).$mount('#app')
    
    

    단일 파일 컴퍼넌트를 사용한 구현이었으므로, App.vue 에는 이하와 같이 기술.

    src/App.vue
    <template>
      <v-app>
        <v-content>
          <header-menu></header-menu>
          <router-view/>
        </v-content>
      </v-app>
    </template>
    
    <script>
    import HeaderMenu from './components/HeaderMenu';
    
    export default {
      name: 'App',
    
      components: {
        HeaderMenu,
      },
    
      data: () => ({
        //
      }),
    };
    </script>
    

    덧붙여서 헤더 메뉴 부분은 다음과 같은 느낌입니다. hidden-sm-and-down , hidden-md-and-up 를 클래스에 부여하여 sm 크기일 때 텍스트를 숨기고 아이콘을 표시합니다. md 사이즈 때 아이콘을 숨기고 텍스트를 표시시키고 있습니다.

    src/components/HeaderMenu.vue
    <template>
      <v-toolbar
        color="teal"
        dark
        class="d-flex justify-center"
      >
        <v-toolbar-items v-for="(item, index) in items" :key="index">
            <v-btn text class="hidden-sm-and-down">
              <router-link v-bind:to="item.path">
                {{ item.title }}
              </router-link>
            </v-btn>
    
            <v-btn text class="hidden-md-and-up">
              <router-link v-bind:to="item.path">
                <v-icon medium>{{ item.icon }}</v-icon>
              </router-link>
            </v-btn>
        </v-toolbar-items>
      </v-toolbar>
    </template>
    
    <script>
    export default {
      name: 'app',
      data () {
        return {
          items: [
            {
              title: 'トップ',
              icon: 'fas fa-home',
              path: '/'
            },
            {
              title: 'プロフィール',
              icon: 'far fa-id-badge',
              path: '/profile'
            },
            {
              title: '作品',
              icon: 'fas fa-folder',
              path: '/works'
            },
            {
              title: 'スキル',
              icon: 'fas fa-code',
              path: '/skills'
            },
            {
              title: 'お問い合わせ',
              icon: 'far fa-envelope',
              path: '/contact'
            }
          ]
        }
      }
    }
    </script>
    
    

    문의 양식



    전송 서버로 gmail을 사용하기 위해 환경 변수에 다음을 추가
    $ firebase functions:config:set gmail.email="gmailID" gmail.password="gmailPassword" admin.email="adminAddress"
    

    밸리데이션은 v-text-field의 rules 옵션을 사용해 구현했습니다.

    ContactForm.vue
    (略)
    
    <v-text-field
      v-model="contactForm.name"
      :rules="contactFormValidation.nameRules"
      label="名前"
      required
    ></v-text-field>
    
    (略)
    <script>
    import { functions } from '@/plugins/firebase'
    
    export default {
        data: () => ({
          contactForm: {
            name: '',
          },
          contactFormValidation: {
            valid: false,
            nameRules: [v => !!v || '名前は必須項目です'],
          },
        })
    }
    </script>
    (略)
    

    빌드 및 배포


    npm run build 에서 빌드하고 firebase deploy 에서 배포가 완료되었습니다!

    요약



    이번에는 처음으로 vue.js를 사용하여 포트폴리오를 만들었습니다. 앞으로는 서버 사이드와 연계시킨 것을 만들고 싶습니다!

    틀린 곳 등이 있으면, 코멘트로 가르쳐 주시면 다행입니다.

    좋은 웹페이지 즐겨찾기