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를 의미)

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

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 }

]

};

- 실행되는 위치가 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를 얻음