프로젝트 3-4주차
2024-02-26 ~ 03-09 (11일)
Vue.js (2) 프로젝트 진행
1. 프로젝트 예시
https://jeong-dev-blog.tistory.com/4
공공데이터를 활용한 의약품 검색 사이트 구축 #2 프론트엔드 with vue.js
공공데이터를 활용한 의약품 검색 사이트 구축 1. 프로젝트 구성 이번 의약품 검색 사이트 구축 프로젝트에 사용될 구성이다. - 프론트엔드(vue.js) - 백엔드(golang) - 배포서버(AWS EC2) 백엔드에서 공
jeong-dev-blog.tistory.com
https://github.com/sonsurim/vue-movie-browser/tree/main?tab=readme-ov-file
GitHub - sonsurim/vue-movie-browser: Vue.js를 활용한 영화 검색 사이트 🍿
Vue.js를 활용한 영화 검색 사이트 🍿. Contribute to sonsurim/vue-movie-browser development by creating an account on GitHub.
github.com
https://velog.io/@njh4803/Vue.js로-영화-검색-사이트-만들기#
Vue.js로 영화 검색 사이트 만들기
특정한 사이트를 만들 때 페이지를 구분하기 위해서 사용하는 것이 바로 Router 기술이다.Vue.js를 학습하면서 이 Router 기술을 어떻게 우리의 프로젝트에 연결할 수 있는지 살펴보자.구글검색을 통
velog.io
https://chb2005.tistory.com/37#3.1.%20App.vue
[Node.js + Vue.js] 게시판 만들기 2. Vue.js를 사용한 Front Server 구현
디자인적인 부분에 대한 설명은 따로 하지 않음 프로젝트 구조 사용 모듈 Vue(Vue-Cli) 설치 방법 : https://chb2005.tistory.com/20 Vuetify 설치 방법 : https://chb2005.tistory.com/21 axios npm i axios vue-router npm i vue-rout
chb2005.tistory.com
2. 프로젝트 진행
1) 개발 환경 설정
2) Vue CLI 설치 및 프로젝트 생성
3) 깃허브 ; repo 생성, VScode 연동
4) 코드 구현
5) CI/CD
※ 학습은 Vue.js 2 버전을 사용하지만, 실제로 구현은 Vue.js3 버전을 이용하기로 결정하였다. (이유)
1) 개발 환경 설정
크롬 브라우저와 Vue.js Devtools 라는 확장 프로그램을 설치하고, VScode 및 Node.js를 설치한다. Node.js는 LTS 버전을 다운받으면 된다. node.js 설치할 때 npm도 같이 설치되어야 한다.
- Chrome
- Visual Studio Code
- Vue 3 : Volar
- 색 테마 : Night Owl
- 파일 아이콘 테마 : Material Icon Theme
- 뷰 확장 플러그인 : Vetur
- 뷰 코드 스니펫 : Vue VSCode Snippets
- 문법 검사 : ESLint, TSLint
- 실습 환경 보조 : Live Server
- 기타 : Prettier, Project Manager, Auto Close Tag, GitLens, Atom Keymap, Jetbrains IDE Keymap 등
※ Vue.js 2는 Vetur, Vue.js 3는 Volar를 사용하면 된다.
Volar는 Vue.js 개발을 위한 Visual Studio Code 확장 프로그램입니다. Volar은 Vue 3 및 Composition API를 지원하는 Vue.js 애플리케이션의 개발을 향상시키기 위해 만들어졌습니다. Volar은 Vue.js 애플리케이션을 더 빠르고 효율적으로 개발할 수 있도록 도와줍니다.
Volar이 제공하는 주요 기능은 다음과 같습니다:
1. **강력한 타입 추론 및 IntelliSense**: Volar은 TypeScript 기반의 Vue.js 애플리케이션에서 강력한 타입 추론 및 IntelliSense를 제공합니다. 이를 통해 코드 작성 및 디버깅을 보다 쉽게 할 수 있습니다.
2. **향상된 컴포넌트 스냅샷 및 템플릿 지원**: Volar은 컴포넌트 스냅샷을 사용하여 Vue 컴포넌트의 미리보기를 제공하고, 템플릿에서도 IntelliSense를 제공하여 템플릿 코드 작성을 지원합니다.
3. **프로젝트 전체의 타입 추론**: Volar은 Vue.js 프로젝트 전체에서 타입을 추론하고 활용할 수 있습니다. 이는 프로젝트의 타입 안정성을 향상시키는 데 도움이 됩니다.
4. **빠른 코드 내비게이션 및 리팩터링**: Volar은 코드 내비게이션을 향상시키고 리팩터링 작업을 보다 쉽게 만들어줍니다.
5. **디버깅 및 테스트**: Volar은 Vue.js 애플리케이션의 디버깅 및 테스트를 지원하여 개발 과정을 보다 효율적으로 만들어줍니다.
Volar은 Vue.js 개발 생태계에서 많은 개발자들에게 환영받고 있으며, Vue.js 애플리케이션 개발에 사용되는 Visual Studio Code 환경을 개선하는 데 큰 역할을 하고 있습니다.
※ 참고 : 깃을 잘 모르시는 분들은 아래 강의나 도서를 참고해보시길 추천드립니다 :)
- 팀 개발을 위한 GIt, Github 시작하기 강좌(클릭)
- 팀 개발을 위한 Git, GitHub 시작하기(클릭)
2) Vue CLI 설치 및 프로젝트 생성
본격적인 작업 시작을 위해 CLI를 설치하고 프로젝트를 생성하기로 했다.
📌 CLI 설치 후 프로젝트를 생성하는 것이 정석이지만, 프로젝트를 먼저 생성하여 뒤늦게 CLI를 설치했다.
프로젝트 생성 후 CLI를 설치해도 되는지? CLI의 장점은?
Vue CLI를 언제든지 설치하고 사용할 수 있습니다. Vue CLI는 Vue.js 애플리케이션을 개발하기 위한 강력한 도구이며, 프로젝트를 더 쉽게 시작하고 구성할 수 있도록 도와줍니다. 따라서 Vue.js를 사용하여 프로젝트를 개발하려는 경우 Vue CLI를 설치하고 사용하는 것이 좋습니다.
Vue CLI를 사용하면 프로젝트를 초기화하고 구성하는 데 도움이 되는 명령어 및 기능을 사용할 수 있습니다. 예를 들어, Vue CLI를 사용하면 프로젝트 템플릿 선택, 프로젝트 설정 및 구성, 개발 서버 실행, 프로젝트 빌드 등의 작업을 간편하게 수행할 수 있습니다. 따라서 Vue 프로젝트를 시작하려는 경우 Vue CLI를 설치하여 사용하는 것이 좋습니다. Vue CLI를 사용하면 프로젝트를 보다 효율적으로 관리하고 개발할 수 있습니다.
CLI를 그냥 설치하면 에러가 떠서 관리자 권한으로 실행하였다.
sudo npm install -g @vue/cli
잘 설치되었는지 확인하기 위한 작업으로, 버전이 뜨면 잘 수행된거다.
vue -V
@vue/cli 5.0.8
📌 CLI 설치했다면 CDN 코드는 작성할 필요 없다.
Vue CLI를 사용하여 Vue.js 프로젝트를 개발하는 경우 CDN을 사용할 필요가 없습니다. Vue CLI는 Vue.js 프로젝트를 관리하고 빌드하는 데 필요한 모든 것을 제공합니다. Vue CLI를 사용하면 프로젝트에 필요한 Vue.js 라이브러리 및 종속성을 자동으로 관리하고, 필요한 경우 프로젝트에 적절한 버전의 Vue.js를 설치합니다.
CDN을 사용하는 경우는 주로 간단한 웹 페이지 또는 프로토타입을 만들 때이며, 복잡한 애플리케이션 개발에는 적합하지 않습니다. CDN을 사용하면 Vue.js를 직접 포함하고 스크립트 태그로 로드해야 하므로 프로젝트 관리가 어려워질 수 있습니다. 또한 CDN을 통한 Vue.js 로드는 브라우저의 캐시에 의존하여 성능이나 안정성 면에서 제한적일 수 있습니다.
따라서 Vue CLI를 사용하여 프로젝트를 개발하는 경우 CDN을 사용할 필요가 없습니다. Vue CLI를 통해 Vue.js를 관리하고 프로젝트를 구성하는 것이 더 효율적이고 안정적입니다.
다음으로 프로젝트를 생성했다.
npm create vue@latest
참고한 사이트는 다음과 같다.
3) 깃허브 ; repo 생성, VScode 연동
CI/CD 관리를 위해서 ETL 작업 레포, 프론트엔드 레포, 백엔드 레포를 각각 만들기로 하였다. 내가 프론트엔드 레포를 담당하여 생성했다.
- `frontend` repo 생성
- VScode와 연동
- 이 블로그를 참고하려고 했지만 (여기도 같은 내용인듯?)
- 이 방법으로 했다. (혼자서 하다가 뒤늦게 찾은 정리본..)
- 책에서도 이렇게 설명 하네..
- `main` branch 내에 기본 커밋 규칙, 브랜치 규칙을 `docs` 폴더 안에 넣었다.
- `main` 위에서 만든 vue 프로젝트 폴더를 옮겼다.
- `develop` branch 생성하고 test.html 파일을 담았다.
4) 코드 구현
(1) 백엔드와의 API 통신, 부트스트랩 이용을 위한 설치
npm install --save axios
npm install bootstrap
※ 처음에 다른 폴더에서 설치해서 다시 설치했다. 무엇이 맞는 건지는 모르겠다.
부트스트랩을 이용하려면 컴포넌트의 스크립트 태그 안에 import 하면 된다.
<script>
import 'bootstrap/dist/css/bootstrap.css';
</script>
Vue 3에서는 bootstrap.js를 import할 필요가 없다.
Vue 3와 부트스트랩을 함께 사용할 때는 주로 부트스트랩의 CSS 파일만 import하여 스타일을 적용합니다. 부트스트랩의 JavaScript 파일을 import할 필요는 없습니다. 부트스트랩의 JavaScript 파일은 주로 jQuery와 Popper.js에 의존합니다. 그러나 Vue 3에서는 일반적으로 jQuery나 Popper.js를 사용하지 않고, 대신 Vue의 생태계에 맞는 라이브러리나 컴포넌트를 사용하여 동일한 기능을 구현하는 것이 권장됩니다. 따라서, Vue 3에서 부트스트랩을 사용할 때는 주로 CSS 파일을 import하여 스타일을 적용하며, Vue의 컴포넌트 시스템을 사용하여 필요한 기능을 구현하는 것이 일반적입니다.
(2) 상위 컴포넌트 생성 및 라우터 연결
View 5종 생성 (home, result, about, error, noresult)
- App.vue
- main.js : Vue에서 Home, Result, About, Error + NoSearch 페이지를 만들기 위해 기본적으로 설정
- View/Home.vue : 메인 화면
- View/Result.vue : 결과 화면
- View/About.vue : 우리 서비스에 대하여 (우선순위 떨어짐)
- View/Error.vue : 에러 화면
- View/NoResult.vue : 모든 예외 처리 시에 일단 보여줄 화면
검색 결과가 없을 때의 페이지를 깜빡해서 뒤늦게 추가했다.
1순위. home, result
2순위. error, noresult
3순위. about
라우터 설정을 하고, View 5개 파일을 생성했다. 일단 Home에서 검색하면 Result로 보내지는 기능까진 작성하였지만 더 추가를 해야 하기 때문에 구조만 만들어두었다.
// 5개의 View 파일들 구조
<template>
<div>
<h1>Result 페이지</h1>
<!-- 내용 추가 -->
</div>
</template>
<script>
export default {
name: 'Result',
// 컴포넌트 옵션
// 데이터, 메소드, 컴포넌트들 작성 예정
}
</script>
<style>
h1 {
color: #333;
}
</style>
// App.vue
<template>
<div id="app">
<RouterView />
</div>
</template>
<script setup>
import { RouterView } from 'vue-router'
</script>
//main.js
// 필요하다면 css import
import { createApp } from 'vue'
//import { createPinia } from 'pinia'
import { createRouter, createWebHistory } from 'vue-router';
import App from './App.vue'
import Home from './views/Home.vue';
import Result from './views/Result.vue';
import About from './views/About.vue';
import ErrorPage from './views/Error.vue';
import NoResult from './views/NoResult.vue';
const routes = [
{
path: '/',
name: 'Home',
component: Home,
},
{
path: '/result',
name: 'Result',
component: Result,
},
{
path: '/about',
name: 'About',
component: About,
},
{
path: '/error',
name: 'Error',
component: ErrorPage,
},
{
path: '/:catchAll(.*)', // 404 에러 페이지 설정
component: ErrorPage,
},
{
path: '/noresult',
name: 'NoResult',
component: NoResult,
}
];
const router = createRouter({
history: createWebHistory(),
routes: [
{ path: '/', component: Home }, // '/home' 경로에 Home 컴포넌트를 매핑
{ path: '/result/:inputData', component: Result }, // '/result' 경로에 Result 컴포넌트를 매핑하고, inputData라는 동적 매개변수를 정의
{ path: '/noresult', component: NoResult },
{ path: '/about', component: About },
{ path: '/error', component: ErrorPage },
]
});
createApp(App)
//.use(createPinia())
.use(router)
.mount('#app');
1) `createRouter`를 사용하여 라우터를 생성하고, `createWebHistory`를 사용하여 브라우저 히스토리를 설정했다.
2) `routes` 배열에는 홈 경로인 `'/'`에 대한 Home 페이지, '/result' 경로에 대한 Result 페이지, '/about' 경로에 대한 About 페이지, '/error' 경로에 대한 Error 페이지, 그리고 404 에러 페이지를 처리하기 위한 catch-all 라우트가 정의되어 있다.
3) 각 페이지에 해당하는 컴포넌트(`Home`, `Result`, `About`, `ErrorPage`)는 import하여 해당 경로에 맞는 컴포넌트를 설정했다.
4) `app.use(router)`를 사용하여 라우터를 앱에 등록하고, `app.mount('#app')`을 사용하여 앱을 마운트한다.
이렇게 코드를 작성하면 Home, Result, About, Error 페이지가 구성된 Vue 앱을 생성할 수 있다. 각 페이지에 대한 내용은 해당 컴포넌트 파일에서 구현하면 된다. 컴포넌트 구조 초안은 이렇게 구상해보았다. Error와 NoResult는 비슷한 구조가 될 것이다. 우선순위는 진할 수록 높다.
📌 깃허브 브랜치, 커밋 전략 (계획) *수정됨
- basic-structure
- view : 상위 컴포넌트
- 하위 컴포넌트 (Header, Footer)
- basic-styling
- Header, Footer
- 각 Contents div (View 내에 작성)
- Home, Result, NoResult, Error, About
- components-separation
- 각 Contents Component화 → 통신
- qualityup
- final-check
이 내용은 수정되었으며, 자세한 사항은 아래 블로그에서 확인 가능하다.
(3) 기본 하위 컴포넌트 (헤더, 푸터) 구조 생성 - Support
- HeaderWhite
- FooterBlack
Header는 2 종류로 나누고 싶었지만 시간 관계 상 우선순위를 뒤로 하고, 전역으로 헤더와 푸터를 등록하려고 한다.이를 위해서 일단 틀만 만들어 놓았다. 상세한 내용은 계속 수정해나가야 한다. 해당 내용은 팀원의 서포트를 받기로 하였기 때문에 미리 작성해서 넘겼다.
// App.vue
<template>
<header>
<HeaderWhite />
</header>
<div id="app">
<RouterView />
</div>
<footer>
<FooterBlack />
</footer>
</template>
<script setup>
import { RouterView } from 'vue-router'
import HeaderWhite from './components/HeaderWhite.vue';
import FooterBlack from './components/FooterBlack.vue';
</script>
// Header, Footer 구조
<template>
<header>
header : {{ message }}
</header>
</template>
<script>
export default {
data() {
return {
message: 'header'
}
}
}
</script>
<style scoped>
/* 스타일링 */
</style>
일단 여기까지 하고 feature/basic-structure 브랜치를 develop으로 PR할 예정이다.
(4) Vuetify 적용, 유닛 테스트 추가
feature/basic-styling 브랜치를 새로 만들었다.
- Header, Footer의 기본 내용,
- 상위 컴포넌트 내에 각 Contents 영역을 div로 만들 예정이다. 이는 추후에 컴포넌트로 분리할 것이다.
일단 스타일 적용을 위해 부트스트랩을 언인스톨 하고, Vuetify를 추가했다. 부트스트랩을 써보긴 했지만 마냥 익숙한 것만은 아니기 때문에 Vue에 특화된 기능을 써보고자 했다.
npm add vuetify
Vuetify — A Vue Component Framework
Vuetify is a no design skills required Open Source UI Component Framework for Vue. It provides you with all of the t...
vuetifyjs.com
코드에 이벤트 처리와 바인딩이 되어 있다는 것을 알 수 있다.
// App.vue
<template>
<v-app>
<header>
<HeaderWhite />
</header>
<v-main> <!--div id="app" 대신 입력-->
<RouterView />
</v-main>
<footer>
<FooterBlack />
</footer>
</v-app>
</template>
<script>
import { defineComponent } from 'vue';
// Components
import HeaderWhite from './components/HeaderWhite.vue';
import FooterBlack from './components/FooterBlack.vue';
export default defineComponent({
name: 'App',
data: () => ({
//
}),
components: {
HeaderWhite,
FooterBlack,
},
});
</script>
main.js에도 해당 내용 추가하였다.
//main.js <script>
import vuetify from './plugins/vuetify'
import { loadFonts } from './plugins/webfontloader'
...
loadFonts()
createApp(App)
.use(router)
.use(vuetify)
.mount('#app');
그리고 유닛 테스트!
Vuetify에 유닛 테스트가 있길래 한 번 틀을 만들어놓았다. 테스트가 진행되어야 하는 부분에 대한 설정은 나중에 더 필요할 것 같다.
- Jest 및 Vue Test Utils 설치
- Jest 구성 : 루트 디렉토리에 jest.config.js 추가
- 단위 테스트 작성 : 일단 테스트로 components/__tests__/##.spec.js 추가
- Jest 실행하여 유닛테스트 실행 (일단 보류)
- npm run test:unit
추가로 Vue 프로젝트 생성 당시에 Cypress를 설치했었는데, 테스트 자동화 기능이어서 이건 이번에 못 쓸 것 같다.
(5) 하위 컴포넌트 분리 및 통신
feature/basic-styling 브랜치 → feature/structure 브랜치로 이름 변경
- Header, Footer의 기본 내용
- Home, Result 하위 컴포넌트 분리 후 연결 : ①, ②
- NoResult, Error, About 하위 컴포넌트 분리 : ③
① Home.vue/HomeHero 분리 후 Result에 연결하기
HomeHero에서 input 데이터를 받아서 이벤트 처리하여 Home에 보내고, 여기서 판별을 하여 noresult 혹은 Result로 보내는 코드를 작성했다. Result에서는 해당 inputData를 받고 백엔드 API 호출하여 필요한 데이터를 받아올 것이다.
<!-- Home.vue -->
<template>
<HomeHero @input-event="Search" />
</template>
<script>
import HomeHero from '../components/HomeHero.vue';
export default {
components: {
HomeHero,
},
methods: {
Search(inputData) {
console.log('검색어 :', inputData); // 확인용 코드
if (inputData.trim() === '') {
this.$router.push('/noresult');
} else {
this.$router.push({ name: 'Result', params: { inputData: inputData } });
}
}
}
};
<!--HomeHero.vue-->
<template>
<v-app>
<v-container fluid fill-height class="d-flex align-center justify-center bg-light">
<v-row justify="center">
<v-col cols="12" sm="12" md="6" lg="4">
<h1>최저가 유튜브 레시피를</h1>
<h1 style="font-weight: 300;">검색해보세요</h1>
<br>
<!-- 현재 표시할 placeholder를 배열에서 가져옴 -->
<input v-model="inputData" type="text" :placeholder="placeholders[currentIndex]" class="menu-input">
<!-- 버튼 클릭 시 search 메서드 실행-->
<v-btn @click="Search" variant="elevated" size="large" rounded="lg" color="#E84855">
Search
</v-btn>
</v-col>
</v-row>
</v-container>
</v-app>
</template>
<script>
export default {
data() {
return {
inputData: '',
placeholders: ['김치찌개', '계란말이', '된장찌개'], // placeholder를 순서대로 담은 배열
currentIndex: 0 // 현재 placeholder의 인덱스
};
},
methods: {
Search() {
this.$emit('input-event', this.inputData);
}
},
mounted() {
setInterval(() => {
this.currentIndex = (this.currentIndex + 1) % this.placeholders.length;
}, 2000);
},
watch: {
// inputData가 변경될 때마다 실행
inputData(newValue, oldValue) {
console.log('inputData changed:', newValue);
}
}
}
</script>
<style>
.menu-input {
background-color: #eee;
width: 60%;
height: 44px;
border-radius: 10px;
margin-right: 10px;
}
</style>
<!--Result.vue-->
<template>
{{ inputData }}
</template>
<script>
export default {
computed: {
inputData() {
return this.$route.params.inputData;
},
searchResults() {
// 검색어에 해당하는 내용을 가져오는 로직 구현
// 예시로 정적인 데이터를 사용하고, 실제로는 API 요청 등을 통해 데이터를 가져와야 합니다.
const searchData = [
{ id: 1, title: '김치찌개', price: '5,000', ingredients: [{'감자 2개':'500원'}, {'물 100ml':'300원'}] },
{ id: 2, title: '계란말이', price: '1,000', ingredients: [{'계란 5개':'300원'}, {'물 20ml':'None'}, {'소금 한꼬집':'20원'}]},
{ id: 3, title: '메뉴 3' },
];
const filteredData = searchData.filter(item => item.title.includes(this.inputData));
// 가공된 검색 결과에서 필요한 정보만 추출하여 반환합니다.
return filteredData.map(item => {
const { title, price, ingredients } = item;
return { title, price, ingredients };
});
}
},
};
</script>
‼️ 검색어 입력 시 결과 페이지로 라우팅되지 않는 에러 해결
this.$router.push({ name: 'Result', params: { inputData: inputData } });
this.$router.push(`/result/${inputData}`);
첫 번째 방식으로 했는데 수정이 되지 않아서 두 번째 방식으로 수행했더니 됐다. main.js에서 라우터 등록 시에 이름을 설정해야 했다. 라우터 사용 방법에 대해 제대로 이해하고 있지 않아서 꽤 오래 걸렸다.
- 라우터의 이름 기반 라우팅을 사용합니다. 라우터에서 Result 페이지의 이름이 'Result'로 정의되어 있어야 하며, 이 이름을 기반으로 라우팅합니다. name과 params 속성을 사용하여 라우터의 이름 기반 라우팅을 시도하는 방식은 해당 이름을 가진 라우터가 없으면 작동하지 않습니다.
- 경로 기반 라우팅을 사용합니다. 여기서는 문자열 템플릿을 사용하여 동적으로 경로를 생성하고 있습니다. /result/ 다음에 inputData의 값이 동적으로 결합되어 생성된 경로로 이동하게 됩니다. 이 방식은 라우터의 경로를 직접 지정하는 것이므로 라우터에 해당 경로가 정의되어 있다면 동작할 것입니다.
② 하위 컴포넌트 ResultHero, ResultDetail 생성
상위 컴포넌트인 Result에서 받아온 API 데이터를 프록시 처리하여 하위 컴포넌트들에게 보냈다. 위 작업에 비해서 빠르게 끝났다. 다만 데이터 형태를 보고 하나하나 어떻게 받아올지를 추가적으로 더 작성하고, 실제 API 호출 테스트를 해보아야 한다. 이 작업이 오래 걸릴 것 같다.
이 때 Result에는 Template에 해당 내용 추가, script에 component로 각각 하위 컴포넌트를 지정하는 코드만 추가했다.
<ResultHero :inputData="inputData" :searchResults="searchResults" />
<ResultDetail :inputData="inputData" :searchResults="searchResults" />
하위 컴포넌트에서는 프록스를 설정하여 사용하면 된다.
<!-- ResultHero.vue -->
<template>
<div>
<!-- inputData를 사용하는 하위 컴포넌트 -->
<h1>{{ inputData }}</h1>
<h1>최저가 레시피</h1>
<!-- searchResults를 사용하는 하위 컴포넌트 -->
<ul>
<li v-for="result in searchResults" :key="result.id">
<div>{{ result.title }}</div>
<div>Price: {{ result.price }}</div>
</li>
</ul>
</div>
</template>
<script>
export default {
props: {
inputData: String, // inputData props를 정의
searchResults: Array // searchResults props를 정의
}
};
</script>
③ 다른 상위 컴포넌트의 하위 컴포넌트 생성
이 작업은 간단하다. 데이터를 연결할 것이 많지 않으므로, (연결할 내용이 있긴 한데 이번엔 제외해야 할 것 같다) 간단하게 구성하면 끝이다. 그래서 추후 스타일링 작업 시에 같이 진행하고자 한다.
(6) HTTP 통신
feature/api 브랜치 생성
- Home to Result
- post /api/search
HTTP 통신을 위해 먼저 axios를 import 해와야 한다. 로직을 분리하여 db 안에 데이터가 있는지 판별하는 코드를 isindb.js를 만들고, scr 폴더 아래에 api 폴더를 따로 만들어서 관리하였다. 백엔드 api url을 공개하지 않기 위해 Home.vue에서 따로 빼낸 것이다.
// isindb.js
import axios from 'axios'
export async function checkDataInDB(inputData) {
try {
const response = await axios.post('http://your-backend-api-url/check', {
data: inputData
});
return response.data.exists;
} catch (error) {
console.error('데이터베이스 확인 실패:', error);
return false;
}
}
//Home.vue
import { checkDataInDB } from '../api/isindb.js';
export default {
methods: {
async searchResult() {
try {
const isDataInDB = await checkDataInDB(this.inputData);
const route = isDataInDB ? `/result/${this.inputData}` : '/noresult';
this.$router.push(route);
} catch (error) {
console.error('에러 발생:', error);
this.$router.push('/error');
}
}
}
*/
};
⚠️ 백엔드와 연결 에러가 발생하여 추후 다시 도전해봐야 한다. 일단 임시 데이터를 연결하는 코드로 제출했다. (temp-data)
(7) 하위 컴포넌트 스타일링
하위 컴포넌트 간에 우선순위를 정해서 하나씩 css를 적용해나갔다.
💡 배운 점
- 2024-02-26 (월) : 학습 자료 수집, Vue 특징 및 장점 파악, 환경 설정 숙지
- 2024-02-27 (화) : 기초 학습, 프로젝트 진행 순서 정리
- 2024-03-01 (금)
- 진행 - 1) Vue 개발환경 설정
- 2024-03-02 (토)
- 진행 - 2) Vue CLI를 이용한 프로젝트 생성
- 진행 - 3) 깃허브 레포 및 main, develop 브랜치 생성하였고, VS code와 연동하였다.
- 2024-03-03 (일)
- 진행 - CI/CD 학습, 컴포넌트 및 라우터 학습, Vue 프로젝트 예시 정리
- 2024-03-04 (월)
- 진행 - 4) 코드 구현 : (1) 필요한 모듈 설치, (2) View 4종 생성
- 2024-03-05 (화)
- 진행 - 4) 코드 구현 : (2) View 1종 추가 (NoResult), (3) 기본 하위 컴포넌트 (헤더, 푸터) 구조 생성
- 2024-03-06 (수)
- 진행 - 4) 코드 구현 : (3) feature/basic-structure 브랜치 to. develop 브랜치 PR
- 진행 - 4) 코드 구현 : (4) Vuetify 추가 및 유닛테스트 구조 세팅, (5) 하위 컴포넌트 분리 및 구조 생성
- 2024-03-07 (목)
- 진행 - 4) 코드 구현 : (6) HTTP 통신 - 예제 코드, (7) 하위 컴포넌트 스타일링 - Home, Result
- 2024-03-08 (금)
- 진행 - 4) 코드 구현 : (6) HTTP 통신 - 테스트, (7) 하위 컴포넌트 스타일링 - Result, About, Header, Footer
- 2024-03-09 (토)
- 진행 - 4) 코드 구현 : (6) HTTP 통신 - 에러 수정
- 시간 관계 상 일단 더미 데이터로 제출하였고, 추후 코드를 다시 작성해야 한다.
🔖 잘한 것과 잘못한 것
- `학습 및 실습` Vue2 기준인 것이 많아서 하나하나 Vue3와 비교하면서 내용을 업데이트했다.
- `2` 파비콘은 여러 브라우저를 고려하여 icon, shortcut icon 모두 사용했다.
- `2` CLI > 프로젝트 생성 순서를 반대로 했는데 잘 해결했다.
- `3` VScode와 깃허브 연동을 혼자서 잘 수행했다.
- `3` 깃허브 브랜치와 커밋 기준을 정해두어 이대로 수행하였다.
- `4-6` HTTP 통신에 관한 지식이 없어서 시간이 많이 소요되었다.
- `4-7` 하위 컴포넌트 스타일링 코드 작성 시간이 짧아서 효율적이었다.
📝 남아있는 의문과 개선점
- `2` Vue 프로젝트를 처음 생성하여 테스팅툴 같이 이것저것 추가해버렸다. 각각 무슨 기능이고 어떻게 활용하면 되는지?
- `3` 깃허브에서 .github 생성 방법?
- `4-1` 부트스트랩이 잘 작동하는 것 같지 않다. → Vuetify로 변경
- `4-4` 유닛테스트와 CI/CD 흐름? 무엇부터 하는 것이 맞고, 언제 적용하는가?
- `4-6` HTTP 통신 백엔드와 연결하기 (실패하여 다시 도전 필요)
- `4` Vue의 특징을 살린 구조의 코드가 아닌 것 같다. 구조 변경을 어떻게 하는 것이 더 나을지?
☁️ 소감
다른 할 일들이 많아서 온전히 집중할 수는 없었지만 천천히 꾸준히 진행했다. 가볍다고 해서 정말 가볍게 생각했는데 확장성이 있어서 그런지 이것저것 연관지어서 알아야 할 점들이 많아보였다. 알면 좋을 것처럼 보여서 자꾸 관심이 흐르는 것을 막아야 했다.
이전에 코드잇에서 강의를 들을 때, 수강 기간이 끝나서 리액트, Vue.js, Node.js 강의들을 수강하지 못했는데 이를 선수학습했으면 더 좋았을 것 같아서 아쉬웠다.
처음엔 못 느꼈지만 프로젝트가 끝나갈 무렵 학습 내용이 많아질수록, 섣부른 시작에 Vue의 강점을 잘 활용하지 못했다는 점을 발견했다. 다시 코드를 짜면 더 '좋은' 코드를 작성할 수 있을 것 같다.
'Data Engineering > grepp 데브코스 : 프로젝트' 카테고리의 다른 글
Vue.js (4) Vue 프론트엔드 CI/CD를 위한 AWS EC2와 GitHub Action (0) | 2024.05.08 |
---|---|
Vue.js (3) 학습 내용 정리 (0) | 2024.05.07 |
Vue.js (1) 학습 자료, 기본 학습 (0) | 2024.05.03 |
최종 팀플 (4) 웹사이트 기획 및 디자인 (2) | 2024.05.01 |
최종 팀플 (3) 데이터 엔지니어링 : 데이터 분석, 크롤링, ETL (1) | 2024.04.27 |