Nuxt.js 사용 방법
[설치 방법]
vue cli 사용(예전 version)
vue init nuxt-community/starter-template mycloud1
cd mycloud1
npm install (lock 문제가 뜨면 "npm install --package-lock-only" 실행)
npm run dev (여기서 dev는 package.json > scripts > dev를 실행; dev는 development mode를 의미)
create-nuxt-app 사용(다양한 설정 가능)
npm init nuxt-app mycloud1
cd mycloud1
npm run dev
[실행]
- 기본 vue sample(확장자는 vue가 되어야 함)
<template>
<section class="section">
<div class="content">
This is a test.
</div>
</section>
</template>
[기본 문법]
- 자세한 내용: https://ko.nuxtjs.org/guide
- Nuxt.js는 webpack과 Vuex를 핵심으로 구성한 web server 구축 위한 framework
- Folder 구조
pages: Vue file 저장
-. index.vue가 기본 표시 page
-. 각종 routing은 해당 Vue file로 지향
=. 예를 들면 http://localhost/about은 about.vue를 표시함
=. <nuxt-link to="/about">About</nuxt-link>
-. pages에 있는 Vue file이 실제 server에서 동작하려면 어느 곳에서든 <nuxt-link>로 이 Vue file을 연결했어야 함
static: 고정적인 그림, 문서 등을 저장
예를 들어 이 folder는 '~/static/img.png' 혹은 '/img.png'로 접근함
assets: webpack으로 처리할 asset을 저장
이 folder는 webpack에 의해 처리됨
Webpack: JS module(C 언어에서 #include) 지원 system
예를 들어 "~/assets/img.png"로 접근
'~'는 webpack으로 처리하여 source directory를 의미(~ 대신 @ 사용 가능)
'~~'는 webpack으로 처리하여 root directory를 의미(~~ 대신 @@ 사용 가능)
설정을 바꾸지 않으면 ~와 ~~는 동일
layouts: layout에 관련된 file 저장
Main layout은 default.vue로 생성
Nuxt.js가 생성하는 runtime page가 <nuxt/> 부분에 표시 예정
<nuxt/> 위에 있는 내용이 header, 아래에 있으면 footer
components: Vue.js component 저장
middleware: middleware에 사용할 사용자 정의 함수 저장
-. middleware는 rendering 전에 호출되는 사용자 정의 함수의 집합체
plugins: Vue.js application이 생성되기 전에 실행되는 JavaScript plugin을 저장
-. nuxt.config.js에 등록해야 함
-. 일반 예: plugins: [{src: '~/plugins/myFun'}]
=. *.vue에서 사용할 때: import myFun from '~/plugins/myFun';
-. SSR(server-side rendering) 하지 않는 예
=. plugins: [{src: '~/plugins/myChart', ssr: false}]
=. plugins: [{ src: '~/plugins/myBarChart', mode: 'client' }]
store: Vuex Store file 저장
Vuex: state management pattern + library for Vue.js applications(중앙 집중형 상태 관리 library)
Vuex Store: Vuex가 만드는 state, mutation 정보를 중앙 관리하는 핵심 object
= state: Vuex의 data
= mutation: state를 변경하는 logic
modules: Nuxt.js core의 기능을 효과적으로 확장하기 위해 사용하는 함수의 집합체 [링크]
-. Nuxt.js의 booting 과정에서 modules가 순차적으로 호출됨, 이를 통해 server가 필요로 하는 반복적인 기능을 효과적으로 추가할 수 있음
자체 link 설정 방법
HTML에서: ~/assets/img.png 등으로 설정; nuxt-link 사용
Script에서: ~/components/compo.vue 등으로 설정
- JSON 처리 방법
우리 server에 있는 JSON은 import 이용해 string 형태로 읽어들임
test.json 읽는 방법: import strTest from '~/assets/test.json'
읽은 strTest를 parsing: let objTest = JSON.parse(strTest);
다른 server에 있는 JSON은 axios.get() 이용해 object 형태로 읽어들임
[Vue.js 호출]
export default {
name: 'myApp',
data() {
return {};
},
asyncData() {
return {};
},
methods: {
fun() { return {}; }
}
};
- data() & asyncData(): data와 asyncData method: script에서 아래 code처럼 호출, https://nuxtjs.org/api/
data: 일반 data 출력
asyncData: 비동기 data 출력 가능
asyncData는 Vue.js framework에서 data와 통합됨
async-await이 서로 짝을 이뤄야 비동기 명령이 실행됨
Server-side에서 호출됨
입력은 {params}로 전달됨
필요한 결과는 return에 담으면 됨
- asyncData(): Routing할 때 pathname 등의 정보는 asyncData 입력으로 전달됨
Dynamic routing 방법
새로운 folder를 만들고 filename이 '_'로 시작하는 Vue file 생성: 예를 들어 _file.vue
_file.vue 안에 asyncData를 생성하면 pathname 입력이 params.file에 전달되어 dynamic routing 실행
- methods: 함수 정의 필요할 때는 methods 안의 object으로 정의
methods에 정의된 다른 함수를 호출하고 싶으면 "this.fun()"처럼 호출
- mounted(): web browser가 새로고침될 때 실행될 기능은 mounted()에 정의
data와 asyncData에 정의된 변수를 참조하고 싶으면 "this.a"처럼 호출
methods에 정의된 다른 함수를 호출하고 싶으면 "this.fun()"처럼 호출
비동기 실행에는 async-await 사용
- created(): Vue instance가 생성될 때 호출되는 함수
-. HTML DOM은 생성되지 않았으므로 HTML에는 접근할 수 없음
- destroyed(): Vue instance가 파괴될 때 호출되는 함수
-. SPA에서 page가 바뀔 때는 Vue instance가 파괴되므로 destroyed() 함수가 호출됨
- Script에서 client-side rendering 확인 방법
if (process.browser) { ... }
if (process.client) { ... }
nuxt.config.js 설정
module.exports = {
plugins: [
{ src: '~/plugins/myPlugin', ssr: false }
]
};
vue-no-ssr 사용: https://github.com/egoist/vue-no-ssr
- 실행되는 위치가 server인지 확인: if (process.server) { ...}
[Modules]
- Module이 여러 vue file에 중복적으로 추가되는 작업 방지
nuxt.config.js 설정: 예를 들어 axios를 전체에서 한 번만 추가
build: {
vendor: ['axios']
}
-> vendor has been deprecated due to webpack4 optimization
- axios: Node.js에서 HTTP 기능 사용, https://github.com/axios/axios
axios를 쓰려면 npm install axios로 Nuxt.js가 있는 folder에 설치를 먼저 해야 함(-g를 이용해 전역으로 설치하지 말 것)
GET
// Make a request for a user with a given ID
axios.get('/user?ID=12345')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
axios.get() 만 사용하는 것도 가능
axios.get()을 받는 값은 {data}만 가능
-> axios.get()으로 얻은 data를 획득하려면, axios.get().data로 접근해야 함
- vue-no-ssr: 편리하게 server-side rendering 방지, https://github.com/egoist/vue-no-ssr
<no-ssr><client-only> 안에는 단 하나의 component/element만 있어야 함
[Context]
Nuxt lifecycle(asyncData, plugins, middleware)에서 사용할 수 있는 Nuxt에서 Vue로 가는 부가적인 객체(object)나 매개변수(params)의 집합체 객체
Univeral key를 이용해 객체(object)나 매개변수(params)에 접근할 수 있음
-. route: Vue Router의 현재 routing 정보를 담고 있는 instance인 route를 저장하고 있음
[CSS 적용]
- Bulma framework 사용
*.vue에 있는 모든 style 제거해야 함
- nuxt.config.js sample
head: {
title: 'Nuxt.js Sample',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: 'Simple test of Nuxt.js' }
],
link: [
{
rel: 'stylesheet',
href: 'https://cdn.jsdelivr.net/npm/bulma@0.9.2/css/bulma.min.css',
},
],
script: [
{
defer: '',
src: 'https://use.fontawesome.com/releases/v5.15.3/js/all.js',
},
],
[Toast UI Chart]
nuxt.config.js
link: [
{
rel: 'stylesheet',
href: 'https://cdn.jsdelivr.net/npm/bulma@0.9.2/css/bulma.min.css',
},
{
rel: 'stylesheet',
href: 'https://uicdn.toast.com/chart/latest/toastui-chart.min.css',
},
],
script: [
{
defer: '',
src: 'https://use.fontawesome.com/releases/v5.15.3/js/all.js',
},
{
src: 'https://uicdn.toast.com/chart/latest/toastui-chart.min.js',
},
],
plugins: [{ src: '~/plugins/myBarChart', mode: 'client' }],
myBarChart.js
export default function(elementName, data) {
if (typeof elementName != 'string') return false;
const el = document.getElementById(elementName);
if (el == null || el == undefined) return false;
const options = {
chart: {
width: 'auto',
height: 'auto',
},
};
toastui.Chart.barChart({ el, data, options });
return true;
}
chart.vue
<template>
<div>
<div id="chartArea" :style="`width:100%;height:${chartHeight}px`"></div>
</div>
</template>
<script>
import myBarChart from '~/plugins/myBarChart';
let showChart = false;
const barData = {
categories: ['2012', '2014', '2016', '2018', '2018'],
series: [
{
name: '시장 규모 (억원)',
data: [9000, 14000, 23000, 37000, 58000],
},
],
};
export default {
data() {
return { chartHeight: 300}
}
mounted() {
if (!showChart && process.client) {
if (!myBarChart('chartArea', barData)) return;
showChart = true;
}
},
destroyed() { showChart = false;}
};
</script>
[HTML Form]
SPA 철학에 맞도록 HTML Form이 submit을 하지 못하게 함
<form @submit.prevent="submitInput">
<input type="text" v-model="name" />
<button type="submit">Submit</button>
</form>
대신 this.$router(SPA를 위한 Vue Router의 전체 instance를 의미)를 이용해 원래 submit 기능을 우리가 직접 구현함
-. $route는 현재 routing 정보를 담고 있는 instance($router와 구별해야 함)
export default {
data() {
return {
nameField: 'name',
name: null,
};
},
methods: {
submitInput() {
this.$router.push('/search?' + this.nameField + '=' + this.name);
},
},
};
Form data를 받는 방법: 예시) search.vue를 만들어서 넘어온 Form data를 다음처럼 받음
asyncData(context) {
return { name: context.route.query.name };
}
-. 현재 routing 정보를 담고 있는 context.route에 접근해서 query 객체를 얻음 -> query의 field는 "name"으로 가정하므로 query.name으로 value를 얻음
[참고 문헌]
- Setup과 도움말: https://nuxtjs.org/guide/installation/
vue-cli 미리 설치 필요: "npm install -g vue-cli" 실행 @ Node.js command prompt
"vue init nuxt-community/starter-template <ProjectName>" 실행 @ Node.js command prompt
- Create a static site in 15 minutes or less using Vue/Nuxt and Netlify
- Create Fantastic Forms in 15 Minutes or Less Using Vue/Nuxt and Netlify
- Nuxt .js is perfect framework for the landing page
- Nuxt Authentication from Scratch
- Creating a Website with Nuxt.js and WordPress REST API
- Build a Server-Side Rendered Vue App with Nuxt.js
- Building server-rendered apps in Vue using Nuxt.js
- Why Your Third-Party Plugin Don’t Work in Nuxt and How to Fix it
- Universal application code structure in Nuxt.js
- Axios Lessons for VueJS Developers Ep. 1