Vue 앱 만들기 (4 : 최종) – 앱 화면 만들기

이틀동안 Vue 설치와 Visual Studio Code(VSCode), Android Studio, Nativescript를 설치하고 간단한 Vue Web App을 만들어보고 Android 개발 환경까지 준비를 다 했다.

이제 간단한 Android용 앱을 하나 만들어 개발용 갤럭시탭에 띄워 보려고 한다.

C:\project\vue 폴더에 만든 vue-farm 폴더에서 계속 작업한다. vue-farm 폴더가 없으면 프로젝트를 만들려고 하는 폴더 ( \project\vue)에서 tns create vue-farm 이라고 치면 폴더가 만들어지고 vue-farm 프로젝트 기본 파일들이 생성된다. 이 vue-farm 폴더 내에서 npm  install  –save  nativescript-vue 라고 명령을 내려 vue-farm 프로젝트에 nativescript-vue를 추가시켜 준다.

VSCode를 띄워서 메뉴의 파일 > 폴더열기를 선택해서 C:\project\vue\vue-farm 폴더를 선택한다.

대략 이런 폴더 구조가 보인다. 여기서 app 밑에 있는 app.js를 열어보면 간단한 정보를 보여주기 위한 페이지를 띄우는 스크립트가 보인다.

[app.js 파일]
import Vue from 'nativescript-vue'

import Home from './components/Home'



new Vue({
  render: (h) => h('frame', [h(Home)]), 
}).$start()

음…Vue.js 예제 파일에서 보던 App.js와는 좀 다른 모양이다. 대충 구조는 Vue() 에서 render 함수를 통해 프로그램이 시작되는 것을 알 수 있다.

이 파일을 약간 수정한다. components 폴더 아래에 App.vue를 만들어서 쓸 예정이므로 Home을 빼고 App를 추가한다.

import Vue from 'nativescript-vue'

/* 삭제되는 라인  import Home from './components/Home' */
import App from './components/App'

new Vue({
  render: (h) => h('frame', [h(App)]), // Home이 App 로 바뀌었다.
}).$start()

import Home 라인은 필요없으니까 삭제를 한다.

다음엔 components 폴더 아래에 App.vue와 Post.vue 두개의 파일을 만든다. 소스는 git의 Instagram-NativeScript-Vue 프로젝트를 참조하였다.

App.vue 파일은 git에서 다운로드 받은 App.vue 파일을 복붙한 다음 하나씩 수정을 하면서 구조를 파악했다.

[App.vue 파일]
<template>
  <Page>
    <ActionBar>
      <StackLayout>
        <Image class="logo" src="~/assets/images/logo.png" />
      </StackLayout>
    </ActionBar>

    <ScrollView>
      <StackLayout>
        <Post v-for="(item, index) in posts" 
                    :key="index"
                    :Image="item.Image"  
                    :Favor="item.Favor"

      />
      </StackLayout>
    </ScrollView>
  </Page>
</template>

<script>
  import Post from './Post'
  export default {
    data(){
      return{
        posts: [
          { Image: 'https://cdn.pixabay.com/photo/2022/09/21/05/39/birds-7469509_960_720.jpg', Favor:0 },
          { Image: 'https://cdn.pixabay.com/photo/2022/02/08/09/28/boats-7001054_960_720.jpg' , Favor:0},
          { Image: 'https://nespy2aub3if2yow3fcm0t5y-wpengine.netdna-ssl.com/files/2013/11/conhe%C3%A7a-londres-635x359.jpg', Favor:0 },
          { Image: '~/assets/images/1000454324980_i1_1200.jpg', Favor:0 }
        ]
      }
    },
    components: { Post }
  }
</script>

<style lang="scss" scoped>
  ActionBar {
    background-color: #f5f5f5;
    color: #ffffff;
  }
  .logo{
    width: 100;
  }
  .message {
    vertical-align: center;
    text-align: center;
    font-size: 20;
    color: #333333;
  }
</style>

수정한 부분은 중간의 Image Url들을 실제 pixabay에 있는 이미지 주소들로 몇개 변경해 본거고 마지막 Image Url은 로컬에 있는 이미지도 되는지 샘플로 한번 넣어봤다. 그리고 각 Image에 Favor라고 하는 변수들을 초기값을 포함하여 지정해 두었다.

이 때 마지막 Image 파일의 주소에 해당하는 실제 파일은 app 폴더 아래의 asset 폴더에 images라고 하는 폴더를 생성하여 그 안에 넣어두어야 한다. 그 작업은 Windows 탐색기 상에서 작업을 하면 되겠다.

다음은 Post.vue 파일이다.

[ Post.vue 파일 ]
<template web>
  <div class="post">
    <div class="post__profile" @click="goTo('profile')">
      <div class="post__imgProfile">
        <img src="~/assets/images/1000486794501_i1_1200.jpg" style="width: 100%">
      </div>
      <strong>홍길동</strong>
    </div>
    <img class="post__image" :src="Image">
    <div class="post__desc">
      <p>{{ Description }}</p>
    </div>
    
  </div>
</template>

<template native>
  <StackLayout class="post">
    <FlexboxLayout class="post__profile" @tap="goTo('profile')">
      <StackLayout class="post__imgProfile">
        <Image
          src="~/assets/images/1000486794501_i1_1200.jpg"
          style="width: 100%"
        />
      </StackLayout>
      <Label text="홍길동" />

    </FlexboxLayout>

    <Image
      class="post__image"
      :src="Image"
    />
    <FlexboxLayout class="post__desc">
      <Label
        textWrap
        :text="Description"
      />
    </FlexboxLayout>
    <WrapLayout>
        <Button text="좋아요" width="50%" @tap="increase()" />
        <Label :text="Favor" width="30%" />
    </WrapLayout>
  </StackLayout>
</template>

<script>
  const { VUE_APP_MODE } = process.env;

  export default {
    props: {
      Image: String,
      Description: String,
      Favor:Number
    },
    methods: {
        goTo(route){
        VUE_APP_MODE === 'web' ? this.$router.push(route) : this.$navigator.navigate(route)
        },
        increase() {
            this.Favor++;
        }
    }
  }
</script>

<style lang="scss" scoped web>
  .post{
    margin-top: 20px;
    width: 100%;
    &__profile{
      display: flex;
      flex-direction: row;
      padding: 0 10px 10px 10px;
      align-items: center;
      strong{
        margin-left: 10px;
        font-size: 13px;
        font-weight: 500;
      }
    }
    &__imgProfile{
      width: 35px;
      height: 35px;
      border-radius: 50%;
      overflow: hidden;
    }
    &__image{
      width: 100%;
    }
    &__desc{
      padding: 10px;

      p{
        font-size: 12px;
      }
    }
  }
</style>


<style lang="scss" scoped native>
  .post{
    margin-top: 20;
    &__profile{
      padding: 0 10 10 10;
      Label{
        margin-left: 10;
        font-size: 13;
        font-weight: 500;
      }
    }
    &__imgProfile{
      width: 35;
      height: 35;
      border-radius: 100;
      overflow: hidden;
    }
    &__desc{
      padding: 10;

      Label{
        font-size: 12;
      }
    }
  }
</style>

여기서 수정한 부분은 <template native> 부붙과 <script>의 propts 부분이다. <template native>는 native 즉 Android 화면에서 뜰 때 참조하는 부분이고 <template web>은 웹브라우저에서 뜨는 환경에서 참조하는 부분이다. template web 부분을 아무리 고쳐도 Android에는 반영되지 않으니 조심해야 한다.

<script>의 props 부분에는 Favor라고하는 변수를 추가하고 버튼을 눌렀을 때 하나씩 증가하는 이벤트 함수를 정의해 주고 이를 <tepmplate native>에 있는 <Button>에 @tab 이벤트로 추가해 주었다.

전체적인 구조를 설명하자면 Post.vue에서 Image Element와 “좋아요” 버튼, 사용자 명 등을 레코드 형식으로 정의하고 App.vue는 이러한 Post.vue Object를 읽어서 data에서 공급받은 정보를 하나씩 대입해서 화면에 반복적으로 뿌려주는 역할을 하는 앱이다.

필요한 image 파일들은 app\asset\images 폴더에 저장해 주고 ( logo 파일, 사용자 프로파일용 사진, Image 리스트 중 로컬에서 보여질 파일 등) 모두 저장한다.

Command prompt 를 실행시켜 vue-parm project 폴더로 이동한다.

C:\> cd \project\vue\vue-farm
C:\project\vue\vue-farm >

이제 Android 기계(핸드폰이나 갤탭 등)를 USB로 연결하고 다시 한번 Android 설정 화면의 가장 아래에 있는 개발자 옵션에서 USB 디버깅이 On 되어 있는지 확인한다. 만약 연결할 기계가 없으면 PC 상에서 그냥 가상기계가 뜨도록 하면 된다.

C:\project\vue\vue-farm> ns run  android

특별히 에러가 나지않으면 Android 기계가 화면을 깜빡이다가 갑자기 앱 화면이 뜬다. 아직 본격적인 화면과는 거리가 멀지만 뭔가 프로그램의 느낌이 나는 화면이 뜬다.

좋아요 버튼을 누르면 숫자가 0에서 1씩 증가하는 것을 볼 수 있다. 화면의 다른 곳을 잘못 누르면 에러가 나고 화면이 에러 로그로 가득 차는데 이는 goTo(‘profile’)의 route가 지정은 되어 있으나 정의되어 있지 않아 쉽게말해 링크가 깨어져 있어서 발생하는 에러이다. route에 대해서는 아직 손대지 않았으니 조금 문서들을 들여다 보고 바꿀 예정이다.

이상으로 vue의 설치와 nativescript 설치를 통해 android App 개발의 첫발을 떼는 것 까지 해 봤다. 혹시 이것저것 자료 찾기 귀찮거나 해도 잘 안되는 사람들은 머리를 비우고 그냥 한번 쭉 따라해 보면 가볍게 성공하지 않을까 싶다.

단, 주의할 점은 시간이 지남에 따라 모든 프로그램들의 버전들이 약간씩 바뀌고 버전의 변경에 따라 소스 문법이나 컴포넌트 사용법들이 약간씩 달라지는 데 이런 점은 각 버전에 맞는 문법과 사용 방법을 다시 한번 참조해야 할 것이다.

끝.

Vue 앱 만들기 (3) – Nativescript 설치

Vue를 설치하고 기본 프로그램 수정을 해서 메뉴와 헤더를 가진 페이지 레이아웃을 개발해보았으니 이제 본격적으로 앱을 만들기 위한 단계로 들어가 보겠다.

먼저 navtivescript는 https://nativescript-vue.org/ko/docs/introduction/ 사이트에서 차근 차근 읽어보는 것이 좋다. 우선 nativescript를 설치한다.

많은 warning이 쏟아져 나온다. 모두 버전의 차이로 더이상 지원되지 않는 기능이라거나 높은 버전의 패키지를 참조해야 한다는 메시지들이다. 잘 모르지만 일단 스킵하고 문제가 생기면 다시 설치하기로 했다.

Windows 환경에서 앱을 개발한다고 하면 우리가 잘 아는 삼성 갤럭시 시리즈 핸드폰과 같은 Android 환경에서 돌아가게 하든 애플의 iOS 환경에서 돌아가게 하든 각각의 핸드폰 또는 기계에 맞는 SDK 들이 들어 있어야 한다. SDK는 간단히 말하면 Development Kit(개발 킷)이다. 이 개발 킷으로 개발을 하면 프로그램이 Android든 iOS든 올라가서 각OS에 있는 기본 기능을 호출하면서 돌아가게 되는 구조이다.

그래서 Android든 iOS를 위한 SDK를 설치해야 한다. 그런데 iOS SDK(아이폰, 아이패드용)은 애플 컴퓨터의 Mac OS에서 가능하므로 일단 Linux와 Windows 를 사용하는 사람은 일단 Android용 SDK만 설치해 보기로 한다.

설치해야 하는 것은 node.js, java의 JDK 그리고 Android Studio라고 한다. node.js는 이미 설치가 되어 있고 JDK는 오라클의 자바 다운로드 사이트에서 다운로드 받아서 설치를 하면 되겠다. 많은 설명 문서에 Windows용 패키지 관리툴인 chocolatey를 쓰라고 권장하는데 아직 익숙하지 않아 하나씩 직접 설치해 보기로 했다.

먼저 Android Studio를 다운로드받아서 직접 설치하기로 했다. SDK만 필요하긴 하지만 실제 Android 환경에서 돌아가는 지 테스트 하기 위해서도 필요하다고 하니 Android Studio를 다 설치 하기로 했다.

다운로드가 완료되면 실행하여 설치를 시작한다.

설치가 끝난 다음 확인을 해 보니 JDK는 Android Studio밑에 자동으로 설치되었고 Android Studio를 처음 실행하면 SDK Components Setup 화면에서 install 할 component를 선택하게 된다. 일단 모든 컴포넌트들을 다 선택한다.

Next를 누를 수 없어서 보니 SDK의 Default 폴더가 한글 사용자 이름이 있는 폴더로 되어 있어서 C:\Project\Android\SDK라는 폴더를 새로 만들고 이곳으로 변경해 주었다. 폴더명에 공백이 있어도 안된다.

나머지는 그냥 계속 Next를 선택하다 마지막에 Finish를 선택하면 실제 설치가 시작된다. 설치는 약 2G 정도의 파일들을 계속 다운로드를 받아가면서 설치하므로 시간이 좀 걸린다.

설치가 완료되면 SDK가 모두 설치되었을 것이므로 일단 종료한다. Android Studio를 모두 설치 했으면 시스템 환경 설정 화면에서 ANDROID_HOME 환경변수를 설정한다.

환경 변수 버튼을 눌러서 환경 변수 화면으로 들어가서 상단의 사용자 변수의 새로만들기를 누른다. 여기서 ANDROID_HOME 경로로 아까 설치한 SDK 경로를 입력해 준다.

그리고 환경변수 화면 하단의 시스템 변수에서 Path를 찾아 편집을 누른다. 여기에 SDK 폴더에 있는 platform-tools 경로를 추가해 준다.

새로 만들기를 누르고 찾아보기 하여 마지막에 platfom-tools 의 경로를 추가해 준다. 이 때 시스템 환경변수 JAVA_HOME 도 확인을 해 보고 등록되어 있지 않으면 등록을 해 준다. JAVA_HOME은 Android Studio가 설치된 폴더의 하위 폴더 중 jre 폴더를 등록해 준다. 일단 “C:\Program Files\Android\Android Studio\jre “를 JAVA_HOME 환경변수로 등록을 했다. 만약 JAVA_HOME이 이미 등록되어 있을 때 JAVA_HOME에 등록된 JAVA와 nativescript가 필요로 하는 자바 버전이 일치 하지 않을 때 Fatal Error를 마주하게 될 수 있으니 반드시 확인해야 한다.

정상적으로 설치와 등록이 끝났는지는 새로운 Command Prompt 창을 띄워서 테스트 해본다.

새로운 command prompt를 안띄우면 ANDROID_HOME이 정의되지 않았다고 그러므로 다시 띄워서 실행한다. 정상적으로 다 설치가 되었으면 모두 체크가 정상적으로 실행된다.

이제 필요한 sdk와 플랫폼은 다 설치 했으므로 프로젝트를 생성한다.

갸웃? 사용 통계정보를 자동으로 보내줘서 도와 달라는 내용인데 일단 거절한다.

어떤 프로젝트를 사용할 것인지 선택하라고 한다. 화살표 키를 이용하여 일단 Vue.js 를 선택한다.

어떤 형태의 template를 사용할 것인지 묻는 내용인데 모두 자신이 없어서 일단 Blank를 선택한다.

열심히 생성 해 주고 있다.

nativescript 설치는 된거 같다.

프로젝트 이름을 vue-farm으로 지어줬기 때문에 vue-farm이 프로젝트 폴더이다. 일단 이 폴더로 들어가서 nativescript-vue plugin을 설치해 준다.

다 된건가? 일단 실행을 해 본다. 명령은 tns run android.

갑자기 핸드폰 화면이 모니터에 뜨고 컴퓨터가 엄청 느려진다. 아 안드로이드를 애뮬레이팅 하나 보다. 화면 핸드폰이 부팅을 한참 한다.

인내를 가지고 기다려 본다. 약 1분 20초 후 화면이 전환되고 또 한 15초 정도 지나서 화면이 뜬다.

Android 에뮬레이터가 메모리 부족으로 실행되지 않거나 너무 느린 경우에는 Android 폰이나 탭(갤럭시 탭같은)을 USB로 PC와 연결하고 개발자 옵션을 켠다. 나는 사용하지 않던 구형 갤럭시 탭을 연결했다.

개발자 옵션은 설정 메뉴의 가장 하단에 있는 “정보”(또는 ‘태블릿정보’)에 들어가서 “소프트웨어 정보”를 선택한 다음 “빌드번호” 섹션을 7번 연달아 탭 해준다음 “설정” 메뉴로 돌아가 보면 가장 하단에 “개발자 옵션”이 생성되어 있는 것을 볼 수 있다.

개발자 옵션에서 “USB 디버깅”을 선택하면 PC가 이 기기를 인식할 수 있게 된다. 다시 PC의 command 창을 열어 “adb devices”를 입력하면 연결된 Android 기기의 시리얼번호가 뜬다. 이 상태에서 nativescript로 앱을 실행시키면 Android 화면에 앱이 실행된다.

Vue 앱 만들기 (2) – VSCode 설정 및 프로그램 수정

Vue.js 설치시 함께 설치한 Visual Studio Code(이하 VSCode)를 이용한 개발 환경에서 프로젝트를 열어보고 디버깅을 해 보도록 하자. 아직 배포환경이나 git, backend, DB 등은 신경 쓸 틈이 없으니 간단한 쇼핑몰 상품 소개 화면을 하나 만들어보자.

1. VS Code 환경 설정

우선 vue.js를 설치하고 생성한 첫번째 프로젝트인 HelloWorld 프로젝트를 VSCode에 불러서 어떻게 디버그 하는지 확인을 하고, Vue에서 만들어 주는 프로젝트는 도대체 어떻게 구성되어 있는지 보도록 하자.

VSCode를 실행시킨다.

기본적인 VSCode의 초기화면인데 Korean Language Pack 과 Live Server를 설치했다. 설치는 화면 제일 좌측에 조각난 네 개의 사각형을 누르면 다른 컴포넌트를 조회할 수 있고 클릭 몇 번으로 간단히 설치할 수 있다. Live Server는 굳이 필요없지만 VSCode에서 디버그를 컨트롤 해 준다고 해서 깔아보았다. 실제로는 Chrome에서 직접 해도 되지만 통합하여 디버그 하는 것이 더 편리할 수 있을거라는 생각에 한번 해 보기로 했다.

파일의 폴더 열기를 선택하여 지난번 만든 프로젝트 폴더(C:\project\vue\hello)를 선택하면 프로젝트 내의 폴더 구조가 자동으로 뜬다. 뜨지 않을때는 제일 좌측 아이콘들 중 가장 위 (탐색기) 아이콘을 선택한다. 프로젝트 내의 src 폴더를 열어보면 다음과 같이 보인다.

아하. 이렇게 디렉토리 구조를 만들어주는 구나 하고 일단 넘어가기로 한다. components 밑에 있는 HelloWorld.vue 파일에 실제 화면에 띄워주는 내용이 들어가 있고, App.vue는 이 내용을 초기화하여 화면에 붙여 주는 부분, main.js는 index.html이 해야 하는 vue 프레임웍을 읽어오는 부분과 이를 화면 <div> element에 mount 해주는 (붙여주는) 역할을 한다는 것을 알 수 있다.

2. 프로그램 실행

터미널을 실행하고 개발용 웹서버를 PC 상에서 실행한다. 지난 시간에 해 보았던 npm run serve 명령이다.

터미널에서 npm run serve 명령을 직접 타이핑 쳐서 실행 시킨다.

화면에서 메뉴에 있는 실행(R)의 디버깅 시작(또는 화면에서 바로 F5 키를 누른다)을 실행하면 웹브라우저 화면이 뜨면서 localhost:8080에 접속하여 HelloWorld 화면을 보여준다. 만약 이상한 에러 메시지를 보여주면 ( 확장자를 인식하지 못한다는 종류의 에러메시지가 뜨는 경우) 프로젝트에 있는 .vscode 폴더에 있는 launch.json 파일을 수정해 준다. 만약 없으면 생성해 주어도 좋다.

launch.json 파일이 정상적으로 저장이 되면 F5키를 누르면 바로 웹 브라우저가 뜨면서 디버깅이 시작된다.

이제 준비가 다 끝났으니 디버깅을 띄워 둔 채 본격적으로 프로그램을 고쳐보자.

3. 컴포넌트 추가

SimpleView 사이트를 참조하여 화면을 세 개의 컴포넌트로 구분해서 작성하겠다. 여기서 말하는 컴포넌트는 하나의 정보 단위로 화면에서 대체로 한개의 구역을 차지하는 덩어리를 말한다. 예를 들어 상단의 고정된 메뉴나, 좌측 세로 메뉴, 우측에 고정되는 링크, 게시판, image를 grid에 통합한 것 등등. 화면에서 하나의 같은 역할을 하는 덩어리들이 모두 컴포넌트이다.

화면을 최상단 header와 좌측 menu, 우측 content의 세개의 레이아웃으로 나누어 보겠다.

우선 VSCode 내에서 프로젝트의 src\components에 세개의 파일을 생성한다.

각각 Header.vue, Menu.vue, Content.vue로 각각 만들어준다.

각 파일의 내용은 거의 비슷하지만 약간씩 다르게 할 예정이다.

[Header.vue 파일]

<template>
    <div class="header">
        <div>Header </div>
        <div>안녕하세요. 다 팔아 쇼핑몰입니다</div>
    </div>
</template>

<script>
export default {
    name: "headerDiv"
};
</script>

<style scoped>
.header {
  position: sticky;
  height: 150px;
  border-bottom: 1px solid #ebebeb;
  background-color:yellow;
}
</style>
[Menu.vue 파일]

<template>
    <div class="menu"> 
        <div>
            Menu 
        </div>
        <div>
            세로로 메뉴를 넣겠습니다
        </div>
    </div>
</template>

<script>
export default {
    name: "menuDiv"
};
</script>

<style scoped>
.menu {
    flex: 1;
    background-color:lightgreen;
}
</style>
[Content.vue 파일]

<template>
    <div class="grid"> 
        Contentㄴ 
            <div>
                <img src="https://cdn.pixabay.com/photo/2022/08/23/09/03/house-7405403_960_720.jpg">
            </div>
    </div>
</template>

<script>
export default {
    name: "nameDiv"
};
</script>

<style scoped>
.grid {
  flex: 2;
}
</style>

하나씩 설명을 하자면 세 개의 파일이 모두 동일한 구조를 가진다.

<template>
     표현할 내용 따위가 html 태그로 들어감
</template>

<script>
    export default {
        name: "고유의_이름"
    }
</script>

<style scoped>
   이 컴포넌트에만 적용되는 디자인 style
</style>

이 때 이름을 지정해 주지 않으면 lint가 컴파일 에러를 쏟아낸다. 그리고 이름도 하나의 단어 예를들어 “School” 등과 같이 하지말고 두개 이상의 단어의 결합을 사용하도록 한다. 현재 또는 미래의 html element 명칭과 혼동되는 것을 막기 위함이라고 하니 불편해도 따라줘야 한다. 이름 사이를 “_”나 두 개 이상의 단어를 섞어서 대소문자로 구분해서 적절히 써 주자.

이제 각각의 파일을 모두 저장해 준다. 그래도 웹브라우저에 뜬 결과물에는 아무 변화가 없다. 왜냐하면 이 각각의 컴포넌트를 화면에 뿌려주는 것은 App.vue가 하는 일이기 때문이다.

이제 App.vue 파일을 고쳐보겠다.

[App.vue 파일]

<template>
  <div>
    <headerDiv/>
      <div class="wrap">
        <menuDiv/>
        <contentDiv/>
      </div>
  </div>
</template>

<script>
import headerDiv from "./components/Header";
import menuDiv from "./components/Menu";
import contentDiv from "@/components/Content";

export default {
  name: "app",
  components: { // 가져온 component 들을 등록합니다.
    headerDiv,
    menuDiv,
    contentDiv
  }
};
</script>

<style>
.wrap {
  display: flex;
}
</style>

<script> 영역에 있는 import는 각 컴포넌트에 지정한 이름을 불러오는 부분이다. 이때 contentDiv는 굳이 파일 명 앞에 “@”를 쓰고 있는데 이는 절대경로로 불러오라는 것이다. ( src 디렉토리를 기준으로 절대경로 )

그리고 <style>은 전체 페이지에 적용되는 style이며 세 개의 컴포넌트를 배치하기 위해 사용한다. 이제 저장하면 자동으로 디버그 페이지가 쨘~ 하고 바뀔 것이다. 만약 vue의 웹서버가 떠 있지 않으면 터미널을 열어 npm run serve를 실행시켜 주고 디버그 창을 열어보거나 웹브라우저로 http://localhost:8080/ 으로 접속해 본다.

이제 감을 잡았을 것이다. 뭐가 컴포넌트이고 어떻게 화면에 보여지고 어디를 고쳐야 할 지를. components 폴더에 만든 각각의 .vue 파일들이 화면의 한 영역을 책임지거나 비지니스로직을 실행할 파일들이다. 그리고 App.vue는 각각의 컴포넌트들을 불러와서 화면에 뿌리는 역할을 한다. 물론 javascript와 html로 웹 페이지를 작성할 때도 java든 php든 python이든 include 등을 통해서 공통 메뉴와 Header, Footer 등을 불러와서 사용한다. 하지만 vue는 개념적으로 각각을 컴포넌트로 분리하여 개발하고 관리하고 필요한 곳에 가져다 쓰는 개념이다. 그래서 다른 템플릿이나 라이브러리를 쉽게 가져다 쓸 수 있다고 계속 강조하는 것이다.

만약 아직 감이 안잡히면 SimpleVue 사이트를 방문하여 예제를 차근 차근 따라 하면서 컴포넌트에 대한 이해를 더 높여보고 vue 프로그램 구조에 익숙해 져 보자.

Vue 앱 만들기 (1) – 첫번째 예제 만들기

Vue로 앱을 만들기 위해서는 우선 vue를 설치해야 한다.  vue.js 의 설치는 앞의 글을 참조하길 바란다. 특별한 오류 없이 설치가 끝난 다음 vue-cli로 프로젝트를 초기화 하고 vue 앱을 작성하면 된다.  가장 기본적인 vue 가이드 문서를 참조하여 하나씩 따라하다 보면 vue 프레임웍을 이해하고 프로그램을 잘 작성할 수 있을 것 같은데, 실제 해보면 … 쉽지 않다.

대체로 외국애들이 작성하는 언어 설명서 ( language reference documents )들은 이해하기 쉽고 초보자들이 잘 따라할 수 있는 문서들인데, vue.js 문서는 기본적인 기술 수준이 javascript와 html, css 등을 어느 정도 이해를 해야 겨우 따라갈 수 있는 수준이라 초보자가 따라가긴 쉽지 않다. 일단 참고 따라해 보라는데 그마저도 쉽지 않은 편이다.

가장 깔끔하게 초보자가 입문할 수 있는 문서는 MDN Web Docs에 설명된 Vue 시작하기를 따라가 보는 것이다.

1. Vue의 이해

먼저 Vue의 정체를 이해하는 것이 중요하다. Vue는 framework으로 앱을 개발하기 위한 server와 client에서 필요한 다양한 기능들이 많이 포함되어 있다. 또한 필요한 부분이 있으면 컴포넌트로 계속 추가하여 사용하면 된다. 마치 자바에서 다양한 기능들이 묶여서 spring과 같은 framework로 구성되어 화면관리, 세션관리, 로그인관리, db연결 관리, bean 생성 및 관리 등을 자동화하고 편리하게 하듯이 Vue에서도 jquery와 같은 HTML 구성요소(html element들)을 조작하거나 관리, 디자인을 고려한 컴포넌트들 통합, 데이터 핸들링,  화면간의 연결 등을 컴포넌트들을 통해 쉽게 통합하여 사용할 수 있다.

만약 웹 페이지를 개발할 때 jquery처럼 간단하게 화면 (흔히 frontend라고 하는 부분 )조작에 필요한 기능만 포함시키기 위해서는 굳이 framework를 모두 포함할 필요가 없다.

vue 시작하기에 설명된 다음의 예제를 보자.

<script>
 export default {
  // Properties returned from data() become reactive state
  // and will be exposed on `this`.
  data() {
     return {
      count: 0
     }
  },
  // Methods are functions that mutate state and trigger updates.
  // They can be bound as event listeners in templates.
  methods: {
       increment() {
          this.count++
       }
  },
  // Lifecycle hooks are called at different stages
  // of a component's lifecycle.
  // This function will be called when the component is mounted.
  mounted() {
      console.log(`The initial count is ${this.count}.`)  
  }
}
</script>

<template>
  <button @click="increment">Count is: {{ count }}</button> 
</template>

이런 예제가 있다. 이 예제를 실행시키는 방법도 구조도 잘 모르지만 무작정 따라하면 버튼을 누를때 마다 1씩 증가하는 프로그램을 만들 수 있다. 그럼 이 방법은 어떨까?

<html>
<head>
</head>
<body>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>

click button <button id="app" onclick="inc()">{{ count }}</button>

<script>
  const { createApp } = Vue

  let btn = createApp({
    data() {
      return {
        count: 10
      }
    }
  }).mount('#app')
  
  function inc(){
    btn.count++;
  }
</script>
</body>

</html>

이 소스는 vue-cli를 설치하지도 않고, node.js와 npm이 설치되지도 않은 상태에서도 똑같이 버튼을 클릭할 때마다 1씩 증가하는 프로그램을 vue를 이용해서 작성할 수 있음을 보여준다.

vue-cli를 이용하여 프로젝트를 생성하고 관리하는 것과 script를 불러와서 사용하는 것의 차이는 무엇일까?

웹페이지에서 vue 패키지를 참조하여 작성하는 경우 사용자 웹 화면에서 vue.js를 참조하여 오브젝트를 생성하고 각 모듈을 컴파일하는 등의 작업을 실행한다. 이 경우 훨씬 자유도가 높을 수도 있고 jquery와 같은 다양한 라이브러리를 혼용하여 사용할 수 있다. 하지만 개발 단계에서 vue-cli를 사용하는 경우 사용자 프로젝트 폴더에 기본적이 환경 설정과 추가적인 패키지와 컴포넌트 등을 미리 포함하거나 툴을 이용하여 편리하게 개발하도록 지원하며, 소스를 컴팩트하게 작성하거나 경량화 할 수 있으며 컴포넌트화 하여 재사용이 가능하도록 한다든지 하는 장점을 추가로 얻을 수 있다.

그러므로 이제부터는 javascript내에 vue.js를 참조하는 방법 말고 vue-cli를 이용하여 프로젝트를 생성하고 컴포넌트를 추가하는 방법을 보기로 한다.

2. 첫 번째 프로젝트

이미 node.js가 설치되어 있고 vue-cli를 설치한 상황에서 프로젝트를 만든다. 우선 프로젝트 디렉토리(폴더)를 생성한다.

Window의 Command 창
C:\> cd \
C:\> mkdir Project
C:\> cd Project
C:\Project> mkdir vue
C:\Project> cd vue
C:\Project\vue> 

사실 window의 explorer를 띄워 그냥 폴더를 생성해도 동일하다.

Linux의 경우 Terminal (term, xterm 등)
[user@centos ~] mkdir project
[user@centos ~] cd project
[user@centos project] mkdir vue
[user@centos project] cd vue
[user@centos vue ]

이제 vue project를 생성한다.

vue create Hello

화살표 키보드를 이용하여 옮겨 다니며 선택할 수 있다. 시험삼아 Manually select features로 해 봐도 좋을 것이다. Manually select features에서는 기본적으로 포함할 번들을 선택할 수 있는 화면으로 넘어가고 Default Vue3로 하면 babel과 lint를 이용하도록 설정된다. 일단 첫번째로 들어가보자. 엔터키를 친다.

뭔가 열심히 설치한다.

컴파일 또는 초기 설정을 다 했단다. 할 일은 제일 마지막 두 줄이다. cd hello 하고 npm run serve를 실행하여 페이지를 웹서버에 띄우는 일이다.

그런데, 살짝 호기심이 들어 도대체 vue가 무슨 작업을 했는지 확인해 보고 싶었다.

C:\project\vue> cd hello
C:\project\vue\hello> dir

내친김에 notepad(메모장)를 이용하여 jsconfig.json 파일도 보고 src 디렉토리 밑에 있는 App.vue 파일도 확인을 해 보았다.

jsconfig.json 파일

{
  "compilerOptions": {
    "target": "es5",
    "module": "esnext",
    "baseUrl": "./",
    "moduleResolution": "node",
    "paths": {
      "@/*": [
        "src/*"
      ]
    },
    "lib": [
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ]
  }
}
src 디렉토리 내의 App.vue 파일

<template>
  <img alt="Vue logo" src="./assets/logo.png">
  <HelloWorld msg="Welcome to Your Vue.js App"/>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'App',
  components: {
    HelloWorld
  }
}
</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;
}
</style>
Public 디렉토리 내의 index.html 파일

<!DOCTYPE html>
<html lang="">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

3. 웹 게시

이제 화면에 띄워서 뭐가 만들어졌는지 확인해 보기 위해 npm run serve도 실행해 보았다.

화면에 지시한대로 웹브라우저를 띄워 http://localhost:8080/ 을 주소창에 입력해 보니 뭔가 뜨긴 떴다.

생성된 프로젝트 구조를 간단히 확인하고 넘어가자면

디렉토리는 node_modules, public, src 세개가 기본적으로 생기고 public 아래에는 favicon과 index.html이 src 아래에 vue와 실제 화면에 표현되는 소스 격의 파일들이 들어 있다. 이 파일들을 수정하여 우리가 화면에 보여주고자 하는 파일들을 만들면 된다. 이 파일들이 build과정을 거치면 html 파일과 css, js 파일들로 분리되어 생성된다.

일단 여기까지 해서 첫번째 vue 페이지를 띄워 봤다. 간단히 구조를 보면 src 디렉토리 내에 기본적인 App.vue 파일과 main.js 파일이 있는데 이 두개의 파일이 화면을 구성하기 위한 기본 요소들이다. 이 파일들을 수정하면 컴파일된 index.html 파일로 우리가 만들고자 하는 화면이 생성되지 않을까 한다. 아직 DB를 끌어오고 화면에 게시판과 차트를 띄우고 핸드폰에서 사진들을 관리하는 기능을 만들기에는 2% 부족하지만 일단 vue로 뭘 할 수 있는지 맛보기 정도 끝냈다고 할 수 있겠다. 끝.

Vue.js 설치

React와 Vue 중에서 많은 고민을 하다가 Vue로 최종 낙점을 했다. Vue를 선택한 이유는 React가 훨씬 멋진 코딩과 높은 자유도, 크로스 플랫폼 앱을 만들기에 더 좋다고 하나 팀 작업을 할때는 좋은 팀웍이나 비슷한 수준의 프로그래머들이 코딩 가이드라인을 정해 놓고 작업하지 않았을 때 코드를 읽는게 너무 짜증나는 경험을 해 본지라 조금 덜 세련돼 보이고, 자유도가 낮아 보이며 제약사항이 있어 보이는 Vue를 선택하고 기능적 차이는 극복할 수 있을 것 같아 Vue로 최종 낙점했다.

1. Visual Studio Code(VS Code) 설치

현재의 사이트 주소는 https://code.visualstudio.com/download 이며 Window 11, User installer 64bit를 다운로드 받아서 설치하였다. 2022년 9월 말 현재 버전은 1.71 . 설치는 윈도우 프로그램의 특징답게 어렵지 않게 설치를 완료하였다. VS Code는 vue와 상관없는 그냥 개발 툴이므로 필수 템이 아니지만 통합된 기능과 익숙한 UI/UX의 장점 덕분에 선택하였다.

2. Node.js 설치

nodejs.org site에 가서 Node.js를 다운로드 받아 설치하였다. 굳이 한글로 된 화면 설명이 필요없으면 https://nodejs.org/en/에서 다운로드 받아도 되며 다양한 다운로드 버전을 보고 싶으면 download 메뉴를 선택하면 된다. 현재 windows (x64) 최신 버전은 18.9.1이며 node-v18.9.1-x64.msi를 다운로드 받았다.

다운로드 받은 프로그램을 바로 실행하여 nodejs를 설치.

중간에 Native Module을 컴파일 하기 위한 툴을 자동으로 설치하겠냐고 물어보는데 과감하게 스킵.

이제 설치가 시작된다.

설치가 완료되면 잘 설치 되었는지 cmd 창(command 창, 명령 프롬프트 창)을 열어 버전을 확인해 본다. Window 하단의 작업 표시줄의 돋보기를 선택하고 cmd를 입력하고 엔터키 실행.

3. vue.js 설치

vue.js는 명령 창에서 npm을 실행하여 설치할 수 있다. 정확하게는 vue의 core에 해당하는 Vue-CLI를 설치한다. npm은 nodejs를 설치함으로써 자동으로 설치되는 패키지 관리 도구(node package manager)이며 nodejs를 기반으로 하는 javascript로 된 다양한 툴들을 설치, 관리할 수 있게 해 준다.

Vue-CLI는Command Line Interface의 줄임말로써 프로젝트를 할 때 가장 기본적인 Vue 환경의 디렉토리 구조, 환경 정보 파일 생성 등 기본적인 칸막이 공사를 해서 프로젝트 파일을 만들어주는 역할을 한다. 즉, 패키지 설치 프로그램인 npm으로 vue.js를 설치한다.

npm이 5개의 deprecated 된 버전에 대한 warnning과 마지막에 자기 자신을 업데이트 해 달라고 메시지를 내고 끝났다.

일단 warning은 warning이므로 유념만 하고 skip하고 vue가 설치되었는지 확인 해 본다.

4. Vue.js를 위한 웹브라우저 Chrome의 확장프로그램 devtools 설치(선택사항)

웹페이지 디버깅시 보통 F12를 눌러 개발자도구를 사용하는데 vue.js와 관련된 확장 tool을 함께 설치한다. 이 기능은 필수 요소는 아니지만 디버깅에 조금 더 유용할 수 있으니 설치한다. 삭제는 chrome 확장 팩 관리 화면 내에서 언제든 삭제가 가능하다. 주소는 https://chrome.google.com/webstore 에서 vue.js를 검색하거나 여기 를 참조해서 직접 설치한다.

실제 웹앱이나 앱을 개발 하기 위해서는 버전 문제와 기능적인 문제로 인해 추가적인 설치 또는 삭제가 필요할 수 있겠으나 기본적인 개발 환경 설정은 어려움 없이 clear.