본문 바로가기
Front/Vue.js

vue.js 실습) 프로젝트 생성 및 분석

by 태하팍 2022. 11. 16.
반응형
주저리
앞서 지난 시간에 vue.js 많은 이론들에 대해서 살펴보다가 말았다ㅋㅋ
이제는 Back-End 개발자들을 위해 하나의 프로젝트를 생성해보면서 vuejs 아키텍처 가이드를 만들어보자! :)

바로 실습 들어가자!

위의 스크린캡쳐는 여러가지 정보를 담고 있다.
모르는 부분이 있다면 한번씩 검색해서 찾아보도록 하자.
1. npm  
     node package manager의 약자로 node.js의 모듈 관리를 하기 위해 사용
    - install  : package를 설치할 때 사용
      예) npm install 패키지명
       package.json에 포함된 의존성 패키지들이 일괄적으로 설치 됩니다.

    - init :  프로젝트를 초기화 해주는 명령어로 package.json file을 만들어줍니다.

npm init --help
Create a package.json file

Usage:
npm init <package-spec> (same as `npx <package-spec>)
npm init <@scope> (same as `npx <@scope>/create`)

Options:
[-y|--yes] [-f|--force] [--scope <@scope>]
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[-ws|--workspaces] [--no-workspaces-update] [--include-workspace-root]

        init -y 옵션으로 명령어를 수행하면 package.json 이 만들어집니다.

npm init -y
Wrote to /Users/teri.epi/Workspaces/package.json:

{
  "name": "workspaces",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

     npm init vue@latest :  Need to install the following packages : create-vue@3.4.0 
     해당 패키지 버전으로 프로젝트를 생성 합니다. 

2. TypeScript
     자바스크립트에 타입을 부여한 언어
     MS에서 개발/관리되고 있는 오픈소스 언어
     자바스크립트가 어렵고 불편하다는 불만에 대응하기 위해 개발
     

3. JSX
     자바스크립트를 확장한 문법
     검색해보면 React에서 많이 사용하고 있음을 알수있다.
     vuejs template 대신 React의 jsx를 사용 가능
     단, 양방향 데이터 바인딩(v-model), 이벤트 수식어(Event Modifiers)를 JSX에서는 지원하지 않음 -> plug-in 이용  

const element = <h1>Hello, world!</h1>;

4. Vue Router
      vue.js에서 페이지간 이동을 위한 라이브러리
      vue.js 공식 라우터
      SPA 특징 : 페이지 이동 시 url이 변경되면 변경된 요소의 영역에 컴포넌트를 갱신
      Requst를 요청하는 방식 아님 주의! (DOM을 새로 갱신하는 것 아님)

5. Pinia
     Vue3에서 추천하는 상태관리 라이브러리
     Vuex, Vue5, Pinia 등 골라서 사용하면 됩니다.

6. Vitest for Unit Testing
     Unit Testing Framework이다.
     java처럼 unit testing을 할 수 있음.

7. ESLint
    ES와 Lint를 합친 것
    ES는 Ecma Script로 Ecma라는 기구에서 만든 Script! 즉, 표준 Javascript를 의미 합니다.
    Lint는 에러가 있는 코드에 표시를 달아놓는 것을 의미 합니다.
    결론 : ESLint는 자바스크립트 문법에서 에러를 표시해주는 도구 입니다.
    설치 : npm install -D eslint

이제 위의 스크린샷 처럼 만들어진 프로젝트를 install하고 실행을 시켜보도록 하자.

cd vuejs-architecture-guide
npm install

npm run dev


결과

 위와 같이 Router기능을 탑재한 프로젝트가 바로 나온다! 와우~

  • 프로젝트의 구성 중 src를 보자!
  • src/ : 실제 대부분의 코딩이 이루어지는 디렉토리입니다.
    • assets/ : 이미지 등 어플리케이션에서 사용되는 파일들이 모여 있는 디렉토리입니다.
    • components/ : Vue 컴포넌트들이 모여 있는 디렉토리입니다.
    • router/ : vue-router 설정을 하는 디렉토리입니다.
    • views/ : router관련 컴포넌트 입니다.
    • App.vue : 가장 최상위 컴포넌트입니다.
    • main.js : 가장 먼저 실행되는 javascript 파일이며, Vue 인스턴스를 생성하는 역할을 합니다.

소스를 분석해보자!
우선 최상위 컴포넌트인 App.vue를 살펴보면 구성은 script, template, style 이다.
그리고 main.ts(Vue 인스턴스를 생성하는 자바스크립트)를 알아보자! 

<script setup lang="ts">
import { RouterLink, RouterView } from 'vue-router'
import HelloWorld from './components/HelloWorld.vue'
</script>

<template>
  <header>
    <img alt="Vue logo" class="logo" src="@/assets/logo.svg" width="125" height="125" />

    <div class="wrapper">
      <HelloWorld msg="You did it!" />

      <nav>
        <RouterLink to="/">Home</RouterLink>
        <RouterLink to="/about">About</RouterLink>
      </nav>
    </div>
  </header>

  <RouterView />
</template>

<style scoped>
header {
  line-height: 1.5;
  max-height: 100vh;
}

.logo {
  display: block;
  margin: 0 auto 2rem;
}

nav {
  width: 100%;
  font-size: 12px;
  text-align: center;
  margin-top: 2rem;
}

nav a.router-link-exact-active {
  color: var(--color-text);
}

nav a.router-link-exact-active:hover {
  background-color: transparent;
}

nav a {
  display: inline-block;
  padding: 0 1rem;
  border-left: 1px solid var(--color-border);
}

nav a:first-of-type {
  border: 0;
}

@media (min-width: 1024px) {
  header {
    display: flex;
    place-items: center;
    padding-right: calc(var(--section-gap) / 2);
  }

  .logo {
    margin: 0 2rem 0 0;
  }

  header .wrapper {
    display: flex;
    place-items: flex-start;
    flex-wrap: wrap;
  }

  nav {
    text-align: left;
    margin-left: -1rem;
    font-size: 1rem;

    padding: 1rem 0;
    margin-top: 1rem;
  }
}
</style>

위 소스에서 <RouterLink to=.. 로 네비게이션을 만들어줄수 있습니다. 
to를 통해 path를 지정해주면 Router의 path와 연결 해줍니다.

<nav>
  <RouterLink to="/">Home</RouterLink>
  <RouterLink to="/about">About</RouterLink>
  <RouterLink to="/blog">Blog</RouterLink>
</nav>

<RouterView />는 현재 Router가 제공하는 컴포넌트가 렌더링 됩니다.

<RouterView />

<RouterView /> 삭제 전 후

기존

 

삭제 : 옆에 Home관련 내용이 랜더링이 안됌

아래 스크립트에서 
import { RouterLink, RouterView } from 'vue-router' : 흔히 사용하는 import라고 보면 된다. 
자바로 보면 import org.xx.vue-router.RouterLink; 
두번째로 import HelloWorld from './components/HelloWorld.vue' 는
components에 있는 HelloWorld.vue를 HelloWorld라는 이름으로 가져왔다.

<script setup lang="ts">
import { RouterLink, RouterView } from 'vue-router'
import HelloWorld from './components/HelloWorld.vue'
</script>

사용은 template에서 사용!
<HelloWorld msg="Vue.js Architecture guide!" />

<template>
  <header>
    <img alt="Vue logo" class="logo" src="@/assets/logo.svg" width="125" height="125" />

    <div class="wrapper">
      <HelloWorld msg="Vue.js Architecture guide!" />

      <nav>
        <RouterLink to="/">Home</RouterLink>
        <RouterLink to="/about">About</RouterLink>
        <RouterLink to="/blog">Blog</RouterLink>
      </nav>
    </div>
  </header>
  <RouterView />
</template>

HelloWorld.vue에 msg(Vue.js Architecture guide!)를 넘겨주고 아래처럼 받아서 출력 해준다.

<script setup lang="ts">
defineProps<{
  msg: string
}>()
</script>

<template>
  <div class="greetings">
    <h1 class="green">{{ msg }}</h1>
    <h3>
      You’ve successfully created a project with
      <a href="https://vitejs.dev/" target="_blank" rel="noopener">Vite</a> +
      <a href="https://vuejs.org/" target="_blank" rel="noopener">Vue 3</a>. What's next?
    </h3>
  </div>
</template>

<style scoped>
h1 {
  font-weight: 500;
  font-size: 2.6rem;
  top: -10px;
}

h3 {
  font-size: 1.2rem;
}

.greetings h1,
.greetings h3 {
  text-align: center;
}

@media (min-width: 1024px) {
  .greetings h1,
  .greetings h3 {
    text-align: left;
  }
}
</style>

그리고 RouterLink와 RouterView는 Router와 연결되어있다.
RouterLink의 path의 path가 들어오면 router/index.ts의 router가 발동 된다.
발동된 결과를 랜더링 해주는것이 RouterView

위에서 /blog를 하나 추가했다.
<RouterLink to="/blog">Blog</RouterLink>
지금은 동작을 하지 않는데 이제 router/index.ts를 수정하여 동작하게끔 해보자.

즉, /blog의 path로 이벤트가 발생하면 원하는 view componet를 연결시켜주면 되는데 방법은 2가지가 있다.

아래처럼 

import BlogView from '../views/BlogView.vue'

를 import 시킨 후 아래처럼 componet를 연결 시키는 방법이 첫번째

{
  path: '/blog',
  name: 'blog',
  component: BlogView
}

아래는 full source 

import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
import BlogView from '../views/BlogView.vue'

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/',
      name: 'home',
      component: HomeView
    },
    {
      path: '/about',
      name: 'about',
      // route level code-splitting
      // this generates a separate chunk (About.[hash].js) for this route
      // which is lazy-loaded when the route is visited.
      component: () => import('../views/AboutView.vue')
    },
    {
      path: '/blog',
      name: 'blog',
      component: BlogView
    }
  ]
})

export default router


Router로 연결된 View Componet 는 만들어줘야 한다. 아래참고!

/blog path에 연결된 view componet

<template>
  <div class="blog">
    <h1>This is an blog page</h1>
  </div>
</template>

<style>
@media (min-width: 1024px) {
  .about {
    min-height: 100vh;
    display: flex;
    align-items: center;
  }
}
</style>

결과는 아래와 같다. Blog 네비게이션을 누르면 위에서 만들어준 BlogView.vue가 오른쪽에 보인다.
머릿속에 전체적인 프로세스가 그려지는가?
요약해보면
1. App.vue (최상위 컴포넌트) 부터 시작하고 vue 인스턴스를 만들어준다. - router 연결 및 mount

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

import './assets/main.css'

const app = createApp(App)

app.use(router)

app.mount('#app')

2.  Router 관련 tag들을 통해 router를 구현
router는 여러가지 path를 분기 시켜주는 역할을 한다.
/blog라는 path를 하나 더 추가했을 때 우리는 RouterLink에 /blog 관련 소스를 추가 해줬다.

    <nav>
      <RouterLink to="/">Home</RouterLink>
      <RouterLink to="/about">About</RouterLink>
      <RouterLink to="/blog">Blog</RouterLink>
    </nav>
  </div>
</header>
<RouterView />

3. 그리고 router 관련 router/index.ts가 발동되기 때문에 관련 소스를 추가(우선 첫번째 방법)
import & path 추가 및 view componet 생성

4. <RouterView> 를 통해 랜더링! 

5. 결과는 아래처럼 Blog를 클릭하면 오른쪽에 This is an blog page를 출력하는 페이지 쉽게 완성!

위 프로세스를 인지하며 2번째 방법으로 router를 구현해보자.

2번째 방법은 이전에 import하는 부분이 삭제되며, compont 연결 부분이 달라진다. 바로 import하는 형태이다.

{
  path: '/blog',
  name: 'blog',
  component: () => import('../views/BlogView.vue')
}

views/BlogView.vue의 출력을 뒤에 !!를 달아서 출력해보자~

그리고 로고 변경을 살펴보자!(V -> G)
아래의 소스에서~! 다른 이미지로 변경을 해보자!

기존 로고

<img alt="Vue logo" class="logo" src="@/assets/logo.svg" width="125" height="125" />

변경 로고

g로고 이미지를 구해서 assets/ 아래에 저장 후 소스에서 src= 부분을 수정해주면 된다.

<img alt="Vue logo" class="logo" src="@/assets/test_logo.png" width="125" height="125" />

 

끝~

반응형