이전에 회사를 다닐 때, 남는 시간에 몰래몰래 vue 공식사이트로 들어가 튜토리얼을 구경했습니다.
그리고 공식 사이트에서 제공하는 튜토리얼 코드를 보면서 '생각보다 어렵지 않네?'라는 느낌이 들었으나...

공식 사이트에서 가르쳐주는 튜토리얼은 그냥 어린이에게 'ㄱ,ㄴ,ㄷ'부터 가르쳐주는 것에 불과했습니다.
어쨌든 이 튜토리얼 코드만 조금 맛보고, 저는 개인 사이트를 vue로 제작하기로 했으나,
결론적으로 목표 기간 내에 사이트를 완성하지 못할 것 같아 react로 먼저 만들었습니다.
그리고 이제 다시 vue를 다시 만져보려 합니다.
친절하게도 한글로 되어있는 공식 사이트에서 퀵스타트 가이드를 읽으며 프로젝트를 생성했습니다.
이때 저는 node.js를 16버전으로 맞추어 두고 작업하고 있었기 때문에 처음부터 오류가 났던 것 같습니다.그래서 nvm을 이용해 node 버전부터 업그레이드를 했죠.
vue도 리액트와 비슷하게, create-react-app과 같은 명령어로 빠르게 세팅을 할 수 있었습니다.

위 이미지에서 설명하듯이 여러 확장 프로그램을 세팅하는 항목이 있는데...
저는 여기서 프로젝트명만 기입하고, 타입스크립트를 설치하지 않았습니다.
때문에 뒤늦게 울며 겨자먹기로 타입스크립트를 세팅하기 위해 오만 가지 방법을 시도해보았으나, 이미 만들어진 프로젝트에서 타입스크립트 기능을 추가하는것은 불가능했습니다. (만약에 성공하신 분이 있다면 제발 방법을 알려주시기 바랍니다)
저는 위 항목에서 대부분 No를 선택했기 때문에 EsLint,Prettier,Vue router와 같은 추가 라이브러리를 일일이 설치해야 했습니다.

프로젝트를 세팅할때 대충 넘기지 맙시다
vue 프로젝트 내에서 scss/sass 파일을 사용하기 위해 sass와 sass-loader,node-sass 패키지까지 설치하였습니다.
지금은 되긴 하는데, node 버전이었나 vue의 버전에 따라 sass의 버전까지 맞춰야 하는 번거로운 상황이 생겼던 것 같습니다.(프로젝트 세팅은 거의 몇 달 전이라 저도 기억이 잘 안납니다.)
어쨌든, 글로벌 css를 적용하기 위해 App.vue(가장 최상단의 세팅 문서)에 import를 시켰습니다.
주석 위의 코드는 대충 무시해주세요.
<template>
<!-- <nav>
<router-link to="/hello">Hello</router-link> |
<router-link to="/about">About</router-link>
</nav> -->
<router-view />
</template>
<script>
export default {
data() {
return {
windowSize: 0,
}
},
mounted() {
window.addEventListener('resize', this.handleResize)
},
beforeUnmount() {
window.removeEventListener('resize', this.handleResize)
},
methods: {
handleResize() {
this.windowSize = window.innerWidth
console.log(this.windowSize)
},
},
}
</script>
//스타일시트
<style lang="scss">
@import '@/assets/scss/reset.scss';
@import '@/assets/scss/global.scss';
</style>
아래는 제가 동일하게 React 프로젝트에서 적용한 App.tsx 코드입니다.
import { ThemeProvider } from "styled-components";
import { theme } from "@/styles/theme";
import { ResetCss } from "@/styles/reset";
import { GlobalStyle } from "@/styles/global";
import { useMediaQuery } from "react-responsive";
import MainLayout from "./components/system/templates/MainLayout";
function App() {
//mediaQuery
const isMobile = useMediaQuery({ query: "(max-width:1023px)" });
return (
<ThemeProvider theme={theme}>
<ResetCss />
<GlobalStyle />
<MainLayout isMobile={isMobile} />
</ThemeProvider>
);
}
export default App;
차이점이 있다면, 리액트에서는 styled-components라이브러리를 통해 ResetCss,GlobalStyle을 컴포넌트 형식으로 만들어 추가해주었다는 점입니다.
물론 vue에서도 styled-components를 사용하기 위해 설치는 해두었지만 사용법을 몰라 직접 import하는 방식을 사용했습니다.
글로벌 css는 사실 폰트를 사용하기 위해 작성했습니다. 기본적인 css와 별 차이가 없긴 합니다.
/*global.scss*/
@font-face {
font-family: 'SUIT-Regular';
src: url('https://fastly.jsdelivr.net/gh/projectnoonnu/noonfonts_suit@1.0/SUIT-Regular.woff2')
format('woff2');
font-weight: normal;
font-style: normal;
}
html,
*,
*:before,
*:after {
font-family: 'SUIT-Regular', sans-serif;
box-sizing: border-box;
::-webkit-scrollbar {
display: none;
}
font-size: 10px;
-webkit-touch-callout: none;
user-select: none;
}
body {
margin: 0;
padding: 0;
color: #333333;
overscroll-behavior-y: none;
}
다행히 여기까지는 스타일이 잘 먹혔습니다.
vue 프로젝트를 처음 만들면 이런 화면이 보입니다.

앞서 글로벌 스타일을 적용했기 때문에 폰트같은 설정들이 바뀐 모습
저는 메인에 보일 페이지를 따로 만들기 때문에, 이 페이지를 없애버릴수도 있었지만 vue의 라우팅 방식을 샘플로 남겨두기 위해 페이지를 분리하기로 했습니다.
router 폴더 내 index.js로 세팅이 가능하다
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
import MainView from '../views/MainView.vue'
const routes = [
{
path: '/',
name: 'main',
component: MainView,
},
{
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(/* webpackChunkName: "about" */ '../views/AboutView.vue'),
},
{
path: '/hello',
name: 'hello',
component: HomeView,
},
]
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes,
})
export default router
/path에는 제가 만드는 MainView 컴포넌트가 보여질 예정입니다. 때문에 /views 폴더에 페이지 컴포넌트를 분리했습니다. routes는 객체 배열로 이루어져 있으며 path, name, component로 구성되어있습니다. 컴포넌트가 <Component/> 와 같이 JSX형태로 되어있지 않다는 점이 특이했습니다.
어쨌든 이런 routes 배열은 createRouter라는 내장 함수에 사용되는 파라미터로 들어가는 듯 합니다. 이렇게 export 된 router는 어디서 쓰일까요?
/*main.js*/
import "@babel/polyfill";
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
createApp(App).use(router).mount("#app");
이렇게 프로젝트 최상단의 main.js (리액트로 따지면 App.js와 동일 경로에 위치한 index.js)에서 사용됩니다. 여기까지는 리액트랑 비슷하네요.
하지만 직접적으로 라우팅 기능을 사용하기 위해선App.vue 에서 <router-view /> 컴포넌트를 추가해주어야 합니다. 맨 위에서 봤던 App.vue의 이 부분이 해당합니다.
<template>
<!-- <nav>
<router-link to="/hello">Hello</router-link> |
<router-link to="/about">About</router-link>
</nav> -->
<router-view />
</template>
저기서 주석 처리된 부분을 활성화시키면, 페이지 상단에 /hello나 /about으로 갈 수 있는 헤더가 생깁니다. 최상단에 위치한 페이지이기 때문에 어떤 페이지를 가든 nav 헤더는 사라지지 않습니다.
프로젝트를 만들면서 오류를 해결하는 시간이 더 많이 걸렸는데, 결국 제때 적어두지 않으니까 다 잊어버려 원통하네요. 이후에는 작업을 할 때마다 글을 써서 아예 잊지 않도록 해야겠습니다.
다음 작업 글에서는 어떻게 vue로 페이지를 구성하는지 좀더 자세히 써보겠습니다.