국내에서도 Vue.js를 사용하는 비율이 점점 높아져가는 것 같습니다. Angularjs, Reactjs보다 진입장벽이 낮고, HTML/CSS와 기본 JavaScript만 다룰줄 알더라도 쉽게 사용할 수 있다는 장점이 있습니다. 또한 vue-cli라는 툴을 이용하여 기본적인 vue 골격을 만들어 웹팩(webpack)까지 통합세트로 운영할 수 있다보니, 고민없이 사용해야한다라는 생각이 점점 강해지는 것 같습니다.

 

분명 처음에는 가볍게 시작을 하면서, 분명 사용하기도 편합니다. 그런데 이 전에 사용했었던 jQuery, Bootstrap. 그리고 그 외의 많은 라이브러리들을 어떻게 추가해야하는지 헷갈릴 수도 있을 것 같습니다. 이는 웹팩이 같이 포함되어 있으면서 외부 라이브러리들을 어떻게 추가하는게 맞는 것인지 명확하게 나와있는 곳 또는 설명해주는 곳이 없기 때문이라고 생각됩니다.

 

저 역시도 jQuery를 추가할 때 webpack config에 끼워넣을려고 고민을 엄청했고, 여러가지 방법을 찾았습니다. 그 중에서 가장 쉬우면서 깔끔하게 추가하는 방법을 포스팅에 정리해보려 합니다.

 

외부 라이브러리를 추가하기 전에 vue-cli를 이용하여 프로젝트 하나를 생성합니다. 이 때, webpack-simple보다는 webpack으로 생성하시는 걸 추천합니다. (나중 웹팩을 추가적으로 만져야할 때 편리합니다.)

 

 

jQuery

jQuery가 뭐하는 건지 잘 모르시는 분 들을 위해 생활코딩 강좌사이트에 나와있는 내용을 언급하도록 하겠습니다.

jQuery란?

      1. 엘리먼트를 선택하는 강력한 방법과
      2. 선택된 엘리먼트들을 효율적으로 제어할 수 있는 다양한 수단을 제공하는
      3. 자바스크립트 라이브러리

네. 그렇다고 합니다.

HTML을 마음대로 조작하며, 기존 JavaScript문법을 좀 더 효율적으로 사용할 수 있도록 도와주는 외부 라이브러리 입니다.

기존 웹사이트에서 jQuery를 추가하려면 HTML에 스크립트 파일을 호출하여 사용하면 됩니다.

 

 

 

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>

view rawvuejs.add.library.1.html hosted with ❤ by GitHub

바로 이런식으로 말이죠.

하지만 Vue에서 위 방식으로 하면 뭔가 하지말아야 할 행동을 하는 것 같기도 하고, 뒤가 찝찝하기도 하고, 뭐라 말할 수 없는 느낌이 있습니다. (위 방식대로 사용해도 문제는 없습니다.)

jQuery를 추가하려면 일단 외부 저장소에서 jQuery 라이브러리를 가져와야겠죠? 해당 프로젝트 루트에서 다음과 같은 명령어를 실행합니다.

 

npm i --save-dev expose-loader

npm i --save jquery

view rawvuejs.add.library.2.sh hosted with ❤ by GitHub

 

라이브러리를 설치하면서 package.json에 같이 추가하게 됩니다.

이 것으로 모든 준비는 끝났습니다. 코드 몇줄로 추가하고 그냥 사용하면 됩니다.

vue-cli로 프로젝트를 생성했다면 /project/src/main.js파일을 확인하실 수 있습니다. 해당 파일에 jQuery사용을 위해 한줄 코드를 추가합니다.

 

import 'expose-loader?$!expose-loader?jQuery!jquery'

view rawvuejs.add.library.3.js hosted with ❤ by GitHub

 

위 코드를 추가하고, npm run dev로 서버를 실행하고 http://localhost:4000/으로 접속하세요. 그리고 개발자도구에서 $를 사용해보세요! 이 것으로 jQuery를 사용할 수 있게 되었습니다.

Bootstrap

반응형 웹사이트를 개발하기 위해 트위터에서 오픈소스로 공개한 UI Framework입니다. jQuery기반으로 되어 있으며, PC, Tablet, Mobile의 스크린을 자유롭게 설계하며 UI를 표현할 수 있는 프레임워크입니다.

Bootstrap의 경우는 javascript코드 이외의 UI를 표현해주는 css파일도 포함시켜줘야 합니다. 그렇다하더라도 코드는 2줄로 추가할 수 있습니다.

먼저 외부저장소에서 Bootstrap을 가져옵니다.

 

 

 

npm i --save bootstrap

view rawvuejs.add.library.4.sh hosted with ❤ by GitHub

그리고 위에서 수정했던 /project/src/main.js을 다시 엽니다.

 

 

 

import 'expose-loader?$!expose-loader?jQuery!jquery'

// 위에서 추가했던 jQuery 밑에 코드를 작성하세요

import 'bootstrap'

import 'bootstrap/dist/css/bootstrap.min.css'

view rawvuejs.add.library.5.js hosted with ❤ by GitHub

 

지금부터 jQuery와 Bootstrap을 동시에 사용할 수 있게 되었습니다.

Bootstrap의 .js.css가 잘 추가되었는지 테스트해보려면 HTML코드작성하는 부분에 아래와 같이 추가해보세요.

 

 

 

<template>

...

<button type="button" class="btn btn-primary" autocomplate="off" data-loading-text="jquery with bootstrap" @click="clickBtn">

...

</template>

<script>

export default {

name: 'jQueryApp',

methods: {

clickBtn (event) {

$(event.target).button('loading')

setTimeout(function() {

$(event.target).button('reset')

}, 1000);

}

}

}

</script>

view rawvuejs.add.library.6.vue hosted with ❤ by GitHub

 

위 코드가 정상적으로 작동한다면 jQuery, Bootstrap(js, css)가 Vue에서 정상적으로 작동하는 것을 확인하실 수 있을 것입니다.

jQuery를 추가하지 못해서 망설였던 분들을 위 방식으로 쉽게 시작하실 수 있으며, jQuery, Bootstrap 뿐만 아니라 그 외의 자주 사용했었던 라이브러리들도 이러한 형식으로 쉽게 추가할 수 있습니다.

Front-end를 개발하고 있음에도 아직 Framework를 사용하고 계시지 않고, 부담스러워하시는 분들이 있다면 지금 당장 시작해보세요. 하루만 투자하면 원하는 웹 애플리케이션을 개발하실 수 있습니다 : )

관련 정보

 

 

출처: https://jinblog.kr/180 [Jin]

 

출처: <https://jinblog.kr/180>

 

Posted by 철냄비짱
,

 

참고자료

Vue CLI 란

Vue CLI 는 커맨드라인 인터페이스 기반의 Vue 프로젝트 생성 도구입니다. Vue 애플리케이션을 개발할 때 기본적인 폴더 구조, 라이브러리 등을 설정해줍다.

1. 설치

npm i -g @vue/cli // vue-cli 3.x
npm i -g vue-cli // vue-cli 2.x

2. 프로젝트 생성

프로젝트를 생성할때 2.x 버전에서는 eslint, unit test, night watch 등등 낯선것들에 대해 선택을 해야만 했는데, 3.x 에서는 default (babel, eslint) 를 선택하면 가장 기본적인 설정으로 프로젝트가 생성됩니다.(나중에 언제든지 옵션을 추가할 수 있습니다.)

vue create '프로젝트 명' // vue-cli 3.X
vue init webpack '프로젝트 명' // vue-cli 2.X

3. 로컬 서버 실행

npm run serve // vue-cli 3.x
npm run dev // vue-cli 2.x

4. node_modules

  • vue-cli 3.x - vue create를 통한 프로젝트 생성 단계에서 함께 설치됩니다.
  • vue-cli 2.x - 프로젝트 생성 후 npm install을 통해 설치합니다.

5. 웹팩 설정 파일

  • vue-cli 3.x 노출 X
  • vue-cli 2.x 노출 O

2.x에서는 webpack.config.js 파일이 루트 디렉토리에 있습니다. 3.x에서는 없기 때문에 설정을 추가하기 위해서는 루트 디렉토리에 vue.config.js 파일을 설정하고 내용을 작성해줍니다. vue-cli 3.x vue.config.js

// vue.config.js
module.exports = {
  // 여기에 옵션을 작성해준다.
}

6. 프로젝트 구성

  • vue-cli 3.x 플러그인 기반으로 기능 추가
  • vue-cli 2.x github의 템플릿 다운로드

2.x 에서는 simple, webpack, webpack-simple, pwa 등 템플릿 리스트 중 하나를 선택해서 프로젝트를 구성했다면, 3.x 에서는 프로젝트에 플러그인 기반으로 원하는 설정 추가합니다.

7. ES6 이해도

  • vue-cli 3.x 필요 O
  • vue-cli 2.x 필요 X

3.x 에서는 ES6 기본 문법 뿐만아니라 축약 문법 또한 알고 있어야 합니다.

 

출처: <https://velog.io/@skyepodium/Vue-CLI-3.X-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0>

 

 

Posted by 철냄비짱
,

vue-axios

Front-End/Vue.js 2019. 12. 30. 08:02

A small wrapper for integrating axios to Vuejs

How to install:

CommonJS:

 

npm install --save axios vue-axios

And in your entry file:

 

import Vue from 'vue'

import axios from 'axios'

import VueAxios from 'vue-axios'

 

Vue.use(VueAxios, axios)

Script:

Just add 3 scripts in order: vue, axios and vue-axios to your document.

Usage:

This wrapper bind axios to Vue or this if you're using single file component.

You can axios like this:

 

Vue.axios.get(api).then((response=> {

  console.log(response.data)

})

 

this.axios.get(api).then((response=> {

  console.log(response.data)

})

 

this.$http.get(api).then((response=> {

  console.log(response.data)

})

 

출처: <https://www.npmjs.com/package/vue-axios>

 

Posted by 철냄비짱
,

Spring boot와 Vue.js를 연동해봅니다.

이 문서에서는 Controller를 어디에 만드는지, cd 명령어는 어디에 입력하는지 등의 모든 과정을 설명하지는 않습니다.

결과물은 이쪽에 --> https://github.com/febdy/Spring-boot-vuejs

 

 

 

Version

Spring boot 2.0.3

Vue.js 2.5.16

Webpack 3.12.0

Gradle 4.x

 

 

 

최종 폴더 구조 예시

 

project

├ src (Spring boot)

│├ main

││ ├ java

││ └ resources

│└ test

├ frontend (Vue.js)

│├ build

│├ config

│├ node_modules

│├  src

││ ├ assets

││ │├ css

││ │├ images

││ │└ js

││ │

││ ├ router

││ ├ shared-components

││ ├ spa

││ │ ├ Member

││ │ │ ├ components

││ │ │ └ Login.vue

││ │ │

││ │ └ Qna

││ │   ├ components

││ │   └ Qna.vue

││ │

││ ├ App.vue

││ └ main.js

││

│├ static

│├ test

│├ .bablerc

│├ .editorconfig

│├ .eslintingore

│├ .eslintrc.js

│├ index.html

│├ package.json

│└ package-lock.json

├ build.gradle

├ gradlew

├ gradlew.bat

└ settings.gradle

 

frontend 구조 참고 : https://github.com/vuejs-kr/vuejs-kr.github.io/issues/28

 

 

 

STEP

 

1. Spring boot

 

 

 

https://start.spring.io/

 

Spring boot는 매우 쉽고 편한 프로젝트 생성 방법을 제공합니다.

Gradle Project를 선택하고 Dependencies엔 Web Thymeleaf 정도 추가해주고 Generate Project로 프로젝트를 받습니다.

옆에 패키지 이름은 원하는 대로 설정.

 

 

 

2. Controller

 

간단히 Controller를 만들어봅니다.

주소/hi를 입력하면 thymeleaf에 의해 resources/templates 안에 있는 index.html에 연결됩니다.

 

 

 

Vue.js

 

1. node.js 설치

 

https://nodejs.org/ko/

 

현재(180718) 기준 8.11.3 LTS 설치했습니다.

 

 

 

2. vue-cli install / init webpack project

 

cd [만들어놓은 Spring boot 폴더] 로 이동해 실행합니다.

 

$ npm install --g vue-cli

$ vue init webpack frontend

 

 

 

3.

 

 

$ cd frontend

$ npm install

 

frontend 폴더 안에 가서 package들을 install합니다.

node_modules라는 폴더가 생깁니다.

 

 

 

4. config/index.js

 

  build: {

    // Template for index.html

    index: path.resolve(__dirname, '../../src/main/resources/static/index.html'),

 

    // Paths

    assetsRoot: path.resolve(__dirname, '../../src/main/resources/static'),

    assetsSubDirectory: 'static',

    assetsPublicPath: '/',

 

 

config/index.js 파일의 경로를 이렇게 수정합니다.

 

 

 

 

 

+) 

application.properties 파일에서

 

spring.thymeleaf.prefix=classpath:/static/

 

추가해줍니다.

static/ index.html 를 읽으려면 thymeleaf의 prefix를 templates가 아닌 static으로 바꿔주어야 합니다.

Vue.js config/index.js의 index 경로를 templates으로 잡으면 spring 설정 없이 그대로 index를 사용 가능 하지만 배포할 때 js 파일을 못 읽을 수도 있습니다.

 

해결 방법은

1. Spring boot에서 thymeleaf의 경로를 바꾸거나

2. Vue.js에서 빌드 설정을 바꿔 static/static/을 인식하게 하는 건데

위가 쉽고 간단하므로 이렇게 해봅니다.

 

 

5. npm run build

 

 

 

$npm run build

 

밑에 파란 글씨의 Build Complete.을 확인합니다.

 

 

 

6. Spring boot server run

 

각자에게 맞는 방법으로 실행해봅니다.

이클립스로는 프로젝트 우클릭 -> Run as -> Spring Boot App.

 

 

 

5. localhost:포트번호/hi

 

브라우저에서 localhost:포트번호/hi를 입력하고 확인해봅니다. Vue 페이지가 뜨면 성공입니다.

 

 

 

* Vue.js 파일 수정 후 바로바로 확인하기

 

Vue.js 파일을 바꾸고 확인할 때마다 build를 해볼 수는 없겠지요.

 

 

 

 

$ npm run dev

 

명령어를 입력하면 개발 모드로 들어가며 파일을 수정하고 저장하는 즉시 바로바로 확인할 수 있습니다.

나오는 방법은

Ctrl + C

 

 

이 서버는 스프링 부트 서버와 별도입니다.

따라서 Vue.js 프로젝트를 확인하기 위해 꼭 Spring boot 서버를 실행할 필요는 없으며

Spring boot 서버에서 확인하고 싶으면 npm run build를 해주어 build된 파일이 다시 src/main/resources에 들어가도록 해야 합니다.

 

다른 툴은 모르겠고 이클립스를 사용중이라면 npm run build를 했을 때 프로젝트 폴더에서 F5를 눌러 새로고침을 한 번 해주세요.

src/main/resources 반영이 제때제때 자동으로 안 됩니다. 스프링 부트 서버도 종료했다가 다시 실행해야 합니다.

 

끝~

 

출처: https://febdy.tistory.com/65 [집]

 

출처: https://febdy.tistory.com/65 [집]

 

출처: <https://febdy.tistory.com/65>

 

Posted by 철냄비짱
,

npm 명령어

Front-End/Vue.js 2019. 12. 30. 08:01

 

안녕하세요. 이번 시간에는 npm 명령어에 대해 알아보겠습니다. npm 명령어는 명령 프롬프트에 입력하는 명령어입니다. 지금까지 봤던 명령어는 npm init, npm start npm run, npm install 정도가 있겠네요. 다양한 명령어가 많지만, 그중에서도 자주 쓰이는 것들에 대해 알아보겠습니다.

npm help 또는 npm 명령어 help는 가장 먼저 알려드릴 명령어입니다. 명령어가 뭐가 있는지 모를 때는 npm help를, 해당 명령어가 무슨 역할을 하고, 가능한 옵션은 뭐가 있는지 궁금하면 가운데 명령어를 넣어서 help하면 됩니다. 예를 들어 init이 무슨 명령어인지 모르겠다면 npm init help하면 되는 거죠.

설치 관련

npm init package.json을 만드는 명령어였죠? 새로운 프로젝트나 패키지를 만들 때 사용합니다.

npm install은 이미 아시다시피 패키지를 설치하는 명령어입니다. npm install 패키지@버전하면 특정한 버전을 설치할 수 있고, npm install 주소하면 특정한 저장소에 있는 패키지를 설치할 수 있습니다. 주소는 주로 Github에만 있는 패키지를 설치할 때 사용합니다. 옵션을 줄 수 있는데 뒤에 --save 또는 -S를 하면 dependencies에(npm5부터는 --save옵션이 기본적으로 설정되어 있기 때문에 안 붙여도 됩니다), --save-dev 또는 -D하면 devDependencies에 추가됩니다. 그리고 -g를 하면 글로벌 패키지에 추가됩니다. 글로벌 패키지에 추가하면 이 프로젝트뿐만 아니라 다른 프로젝트도 해당 패키지를 사용할 수 있습니다.

npm update는 설치한 패키지를 업데이트하는 명령어입니다.

npm dedupe는 npm의 중복된 패키지들을 정리할 때 사용합니다. 가끔 쳐주면 용량도 줄이고 좋습니다.

npm docs는 패키지에 대한 설명을 보여줍니다. 하지만 그냥 npm 홈페이지에 가서 보는 게 정신 건강에 좋습니다.

조회 관련

npm root node_modules의 위치를 알려줍니다.

npm outdated는 오래된 패키지가 있는지 알려줍니다. 오래되었고 package.json에 적어둔 버전 범위와 일치하면 빨간색으로, 오래되었지만 버전 범위와 일치하지 않으면 노란색으로 표시됩니다.

npm ls는 패키지를 조회하는 명령어입니다. 현재 설치된 패키지의 버전과 dependencies를 트리 구조로 표현합니다. npm ll을 하면 더 자세한 정보를 줍니다. npm ls [패키지명]을 하면 해당 패키지가 있는지와, 해당 패키지가 어떤 패키지의 dependencies인지 보여줍니다.

npm search는 npm 저장소에서 패키지를 검색하는 명령어입니다. 패키지의 이름, 설명 또는 키워드를 바탕으로 검색 결과가 나옵니다. 그냥 npm 홈페이지에서 검색하는 게 정신 건강에 좋습니다.

npm owner는 패키지의 주인이 누군지 알려주는 명령어입니다. 또는 여러 명의 주인을 설정하거나 지울 수 있습니다.

npm bugs는 버그가 발생했을 때 어떻게 패키지의 주인에게 연락을 취할지 알려줍니다. 주로 Github의 issues 탭을 엽니다.

로그인 관련

npm adduser은 npm에 회원가입하는 명령어입니다. 로그인도 됩니다. npm login도 똑같은 역할을 합니다.

npm logout은 반대로 logout할 때 사용합니다.

npm whoami는 귀여운 명령어입니다. 이름 그대로 내가 누군지 물어보는 명령어죠. 로그인한 상태라면 자신의 아이디를 알려줍니다.

출시 관련

npm publish는 패키지를 직접 출시하거나 버전 업그레이드를 할 때 사용하는 명령어입니다. .gitignore또는 .npmignore 파일에 적혀있지 않은 파일들은 npm 저장소에 업로드되어 출시됩니다. 여러분도 이제 자신의 패키지를 가질 수 있는거죠. 이 명령어를 사용하려면 여러분은 로그인한 상태여야 합니다. 그리고 패키지의 이름은 선점하는 사람이 계속 쓰기 때문에 이름을 선점하는 것도 중요합니다.

npm deprecate는 이미 낸 패키지를 사용하지 않도록 권고하는 명령어입니다. 자신이 어떤 버전을 출시했는데 치명적인 버그가 있다면 이 명령어를 사용해서 다른 사람들에게 사용하지 말도록 말해줍시다.

npm unpublish는 publish한 패키지를 다시 unpublish하는 겁니다. 하지만 deprecate를 쓰는 게 나은 게 이미 자신의 패키지를 다운로드한 사람들에게 피해를 입힐 수 있습니다.

npm star는 자신이 좋아하는 패키지를 표시하는 기능입니다. 이 star이 많을 수록 인기 패키지이기도 합니다. 심심하시면 제 react-vote나 react-filepicker에 star 해보세요.

npm starts는 특정 사람이 star한 패키지 목록을 확인할 수 있습니다.

npm version은 버전 업데이트를 할 때 사용합니다. 새로운 버전이 나왔다면 npm version [버전]하면 됩니다.

실행 관련

npm start package.json의 scripts에 있는 start 명령어를 실행하는 부분입니다. 만약 start 명령어를 따로 설정하지 않았다면 node server.js가 실행됩니다.

npm stop은 뭔지 알겠죠? npm start했던 것을 멈추는 명령어입니다.

npm restart npm stop 후에 다시 npm start를 하는 명령어입니다.

npm test는 test 명령어를 실행합니다.

npm run은 그 이외의 scripts를 실행하는 명령어입니다. 예를 들어 scripts에 build 명령어가 있다하면, npm run build하면 됩니다.

설정 관련

npm cache는 npm 내의 cache를 보여줍니다. 만약 npm에 문제가 생기거나 하면 제일 먼저 하는 게 npm cache clean으로 cache를 지우는 겁니다.

npm rebuild는 npm을 다시 설치하는 명령어입니다. 에러가 발생했을 시 주로 npm cache clean을 한 후 이 명령어를 쳐서 재설치해봅니다.

npm config는 npm의 설정을 조작하는 명령어입니다. npm config list 하면 현재 설정들을 볼 수 있고, npm set [이름] [값], npm get [이름]으로 속성을 설정하거나 조회할 수 있습니다.

명령어가 많죠? 이중에 자주 쓰이는 명령어는 설치나 업데이트 또는 조회 관련 명령어일 겁니다. 하지만 다른 명령어도 종종 쓰이기 때문에 알아두는 것이 좋습니다.

 

출처: <https://www.zerocho.com/category/NodeJS/post/58285e4840a6d700184ebd87>

 

 

Posted by 철냄비짱
,

자바스크립트뿐만 아니라 모든 언어에서 시간 차이를 구하는 함수는 많이 사용됩니다.

오늘은 자바스크립트에서 Moment.js를 사용하여 시간차이를 구하는 방법에 대해서 알아보도록 하겠습니다.

 

 

Moment.js란?

 

 

Moment.js를 사용하여 시간차이 구하기

(시간1: 과거시간, 시간2: 현재시간 임을 가정합니다.)

      • Sample 1)
        - 시간 1, 시간 2 사이의 일(day) 차이 구하기
        console.log('일 차이: ', moment.duration(t2.diff(t1)).asDays());
      • Sample 2)
        - 시간 1, 시간 2 사이의 시간(hour) 차이 구하기
        console.log('시간 차이: ', moment.duration(t2.diff(t1)).asHours());
      • Sample 3)
        - 시간 1, 시간 2 사이의 분(minute) 차이 구하기
        console.log('분 차이: ', moment.duration(t2.diff(t1)).asMinutes());
      • Sample 4)
        - 시간 1, 시간2 사이의 밀리세컨드(ms) 차이 구하기
        console.log('밀리세컨즈 차이: ', moment.duration(t2.diff(t1)).asMilliseconds());
        <Sample 1,2,3,4 code>

<결과>

      • Sample 5)
        - 시간1, 시간2 사이의 시분초(X시간 Y분 Z초) 차이 구하기

 

 

참조

 

 

출처: https://ithub.tistory.com/196 [Fall in IT.]

 

출처: <https://ithub.tistory.com/196>

 

Posted by 철냄비짱
,

vue-ads-pagination

Vue ads pagination is a vue js pagination component. On the left side you find some information about the shown items. On the right side you can select a specific, the first, last, next or previous page.

All the components can be overriden by your own components, or you can add your own styles to the default components.

View Demo Download Source

Installation

You can install the package via npm or yarn.

NPM

npm install vue-ads-pagination --save

YARN

yarn add vue-ads-pagination

Usage

You can add the vue-ads-pagination component by using the following code in your project.

<template>
    <div id="app">
        <vue-ads-pagination
            :total-items="200"
            :max-visible-pages="5"
            :page="page"
            :loading="loading"
            @page-change="pageChange"
            @range-change="rangeChange"
        >
            <template slot-scope="props">
                <div class="vue-ads-pr-2 vue-ads-leading-loose">
                    Items {{ props.start }} tot {{ props.end }} van de {{ props.total }}
                </div>
            </template>
            <template
                slot="buttons"
                slot-scope="props"
            >
                <vue-ads-page-button
                    v-for="(button, key) in props.buttons"
                    :key="key"
                    v-bind="button"
                    @page-change="page = button.page"
                />
            </template>
        </vue-ads-pagination>
    </div>
</template>

<script>
import '../node_modules/@fortawesome/fontawesome-free/css/all.css';
import '../node_modules/vue-ads-pagination/dist/vue-ads-pagination.css';

import VueAdsPagination, { VueAdsPageButton } from 'vue-ads-pagination';

export default {
    name: 'App',
   
    components: {
        VueAdsPagination,
        VueAdsPageButton,
    },

data () {
        return {
            loading: false,
            page: 5,
        };
    },

methods: {
        pageChange (page) {
            this.page = page;
            console.log(page);
        },
       
        rangeChange (start, end) {
            console.log(start, end);
        },
    },
};
</script>

Vue

Components

VueAdsPagination

Properties

      • page: (type: number, default: 0) A zero-based number to set the page.
        Be aware you need to update the page property by the result of the page-change action!
      • items-per-page: (type: number, default: 10) The maximum amount of items on one page.
      • max-visible-pages: (type: number, default: 5) The maximum number of pages to be visible if their are too many pages.
      • total-items: (type: number, required) The total amount of items.
      • loading: (type: boolean, default: false) Indicates if the current page is loading.

Events

      • page-change: Emitted on creation, to know the initial state, and if another page is clicked. It contains the following parameters:
      • page: (type: number) The zero-based current page.
      • range-change: Emitted on creation, to know the initial state, and if another page is clicked or the total items change and you're on the last page.
        It contains the following parameters:
      • start: (type: number) A zero-based number to identify the first item.
      • end: (type: number) A zero-based number to identify the last item.

Templates

Default

You can add a default template to use a custom pagination detail box.

The scope contains 3 variables:

      • start: (type: number) The included start item.
      • end: (type: number) The included end item.
      • total: (type: number) The total number of visible items.

<template slot-scope="props">
    {{ props.start }} - {{ props.end }} : Total {{ props.total }}
</template>

Vue

Buttons

If you want to use your own buttons, control their behaviour our style them in a different way.

You can create your own button component and loop over it in this slot or use the predefined VueAdsPageButton.

This is a scoped slot that contains an array of buttons.

      • buttons: (type: Array) A list of all buttons currently used. One button is an object that contains the following attributes:
      • page: (type: number||string) This is the zero based page or the string '...'.
        Note that the value of this attribute for the next and previous icons is calculated by the current page.
        If the current page is 2, the previous page will be 1 and the next page is 3.
      • active: (type: boolean) Is the current page active?
      • disabled: (type: boolean) Is the current button disabled?
      • html: (type: string) This string is shown in the button. So you can use icons for the previous and next button.
      • title: (type: string) If you want to add a title to the button, you can fill this attribute.
      • loading: (type: boolean) Indicates if the button has to show a loading icon.

<template
    slot="buttons"
    slot-scope="props"
>
    <vue-ads-page-button
        v-for="(button, key) in props.buttons"
        :key="key"
        v-bind="button"
        @page-change="page = button.page"
    />
</template>

Vue

VueAdsPageButton

This is the default button. If you want to add extra classes. Add the template above and add the class attribute.

Properties

      • page: (type: number||string, default: 0) A zero-based number that represents the page or '...'.
      • active: (type: boolean, default: false) Is the current button active?
      • disabled: (type: boolean, default: false) Is the current button disabled?
      • html: (type: string, required) This string is shown in the button.
      • title: (type: string, default: '') If you want to add a title to the button, you can fill this attribute.
      • loading: (type: boolean, default: false) Indicates if the button has to show a loading icon.
      • disable-styling: (type: boolean, default: false) Remove all styling classes.

Events

      • page-change: Emitted when the button is clicked.

Testing

We use the jest framework for testing this pagination component. Run the following command to test it:

npm run test:unit

GitHub

arnedesmedt/vue-ads-pagination

215

Vue pagination component  Read More

Latest commit to the develop branch on 1-19-2019

Download as zip

Vue.js Examples

A nice collection of often useful examples done in Vue.js

 

출처: <https://vuejsexamples.com/vue-ads-pagination-is-a-vue-js-pagination-component/>

 

Posted by 철냄비짱
,

Moment.js란?

      • 자바스크립트에서는 날짜를 표시할때 Date 객체를 사용합니다. 이때, 특정 형태의 날짜를 나타내기 위해선 직접 함수를 개발해야합니다.
      • 또, 브라우저에 따라 시간대가 다를 경우 이를 고려하여 개발해야하는 번거러움이 있습니다.
      • Moment.js를 사용하면 이 두가지 문제를 해결할 수 있습니다.

 

 

Moment.js 공식 홈페이지

 

Moment.js 설치

      • 홈페이지에서 직접 다운받을 수 있으며, npm과 같은 패키지매니저를 사용하여 설치 할 수 있습니다.

 

Moment.js 사용법

      • 다운받은 js파일은 프로젝트에 import합니다.
      • moment 객체를 사용하여 아래와 같이 여러 형태의 날짜 형태로 표현이 가능합니다.

 

 

 

Moment.js의 다양한기능

 

 

출처: https://ithub.tistory.com/99 [Fall in IT.]

 

출처: <https://ithub.tistory.com/99>

Posted by 철냄비짱
,

Babel

Babel  ES2015+ 문법을 ES5 지원 브라우저에서 해석할 수 있도록 변환해주는 트랜스파일러이다. 하지만 새롭게 추가된 전역 객체들(Promise, Map, Set..)과 String.padStart 등 전역 객체에 추가된 메서드들은 트랜스파일링만으론 해결하기 어렵기 때문에 core-js  regenerator-runtime 와 같은 별도의 polyfill 이 필요하다.

Babel 기반에서 폴리필을 추가하는 방법은 두 가지가 존재한다. babel-polyfill 을 사용하는 방법과 babel-plugin-transform-runtime 을 사용하는 방법이다. 차례대로 살펴보자.

 

 

 

babel-polyfill

babel-polyfill 은 내부적으로 페북에서 만든 Generator Function 폴리필인 regenerator runtime 과 ES5/6/7 폴리필인 core-js 를 주요 디펜던시로 가지고 있다. 가장 유명하고 안정적인 폴리필들을 사용하기 편리하게 랩핑해 놓은 모듈이라고 생각하면 편하다.

babel-polyfill을 사용하려면 먼저 아래와 같이 npm 으로 설치해준다.

# babel-polyfill 디펜던시 추가
$ npm
install --save babel-polyfill

 

그런 뒤에 스크립트 중 최상위 시작지점에 require 혹은 import 해주면, babel-polyfill 은 전역에 직접 폴리필을 추가한다. 즉, 전역 오염이 발생한다.

require('babel-polyfill');

//혹은

import 'babel-polyfill';

babel-polyfill 을 사용할 때의 장점은 어떤게 있을까?

core-js는 먼저 전역에 폴리필을 추가하기전에 해당 기능이 있는지를 체크하므로, 폴리필이 필요없는 최신 브라우저에서는 폴리필없이 동작하게 되어 (babel-plugin-transform-runtime 를 사용하는 것에 비해) 빠르다.

또 전역 객체를 직접 수정하기 때문에 Array.prototype.includes 등 ES2015+에서 새로 추가된 프로토타입 메서드도 문제없이 사용 가능하고, 덕분에 내가 짠 코드가 아닌 npm에서 디펜던시로 받은 라이브러리가 ES2015+ 에서 새롭게 추가된 객체나 프로토타입 메서드를 사용하는지 신경쓸 필요가 없게 되어 개발할 때도 편리하다.

babel-polyfill 을 사용할 때의 단점이라면 실제 사용하지 않는 폴리필도 몽땅 추가되므로 번들링되는 파일의 크기가 커지게 된다는 점이다.

 

 

 

babel-polyfill 사용 시 주의할 점

한가지 꼭 주의할 부분이 있는데, 한 페이지에서 딱 하나의 babel-polyfill 만 허용된다는 점이다. 두 개의 babel-polyfill 을 실행하게 되면 반복적인 전역 객체 수정을 막기 위해 아래의 오류를 발생시킨다.

Uncaught Error : only one instance of babel-polyfill is allowed

 

babel-polyfill 소스를 살펴보면 내부적으로 전역 변수 하나를 두어 babel-polyfill 이 이미 실행되었는지를 체크하고 이미 실행되었다면 무조건(!!!) 오류를 던지는 구조이다.

if (global._babelPolyfill) {
 
throw new Error("only one instance of babel-polyfill is allowed");
}
global._babelPolyfill =
true;

import "core-js/shim";
import "regenerator-runtime/runtime";

...

 

왜 이렇게 극단적으로 오류를 던지게 했을까?

babel-polyfill 의 디펜던시인 core-js 의 ES6/7 폴리필의 경우 두 번 호출되면 내부적으로 오류가 발생되어 정상적으로 폴리필이 적용되지 않는다. 아마도 core-js 가 가지는 이러한 문제점 때문에 babel-polyfill 에 이런 예외처리가 추가된 게 아닐까 추정된다. 

따라서 babel-polyfill 이 두 번 호출되지 않도록 주의해야 한다. 단순히 babel-polyfill 이 두 번 호출되는 것 뿐만 아니라 core-js 의 ES6/7 폴리필이 로드된 상태에서 babel-polyfill 이 로드되거나 babel-polyfill 이 로드된 상태에서 core-js 의 ES6/7 폴리필이 로드되는 것 역시 주의해야 한다.

정리해보면, 싱글 페이지 어플리케이션에서 또다른 폴리필이 호출될 염려가 전혀 없는 환경이라면, babel-polyfill 만으로 IE8 과 같은 레거시 브라우저에서 큰 문제없이 트랜스파일링된 코드를 실행시킬 수 있기 때문에 babel-polyfill 은 가장 편하고 빠르게 폴리필을 적용할 수 있는 방법으로 추천 할 만하다.

 

 

 

babel-plugin-transform-runtime

babel-polyfill 외에 또 하나의 방법은 babel-plugin-transform-runtime 플러그인을 사용해서 Babel 이 트랜스파일링을 하는 과정에서 폴리필이 필요한 부분을 내부의 헬퍼 함수를 사용하도록 치환해주는 방법이다.

Babel 은 내부적으로 _extend 처럼 공통 함수를 위한 작은 헬퍼들을 사용하는데, 기본적으로 모든 파일에 이런 헬퍼들이 추가되기 때문에 이런 낭비를 막기 위해 transform-runtime 플러그인을 사용해서 모든 헬퍼들을 babel-runtime 이라는 모듈을 참조하도록 해준다. babel-plugin-transform-runtime 은 플러그인 이기때문에 빌드 단계(트랜스파일링 단계)에서 동작하게 된다.

transform-runtime 은 코드에 대한 샌드박스도 제공해주는데 내부적으로 core-js 내장하고 여기에 대한 alias 를 생성해서 트랜스파일링 과정에서 폴리필이 필요한 부분들이 이 alias 를 참조하도록 변경해서 전역 오염없이 폴리필이 적용되도록 만들게 된다.

babel-plugin-transform-runtime 플러그인은 내부적으로 babel-runtime 을 디펜던시로 갖는데, babel-runtime 은 또 core-js 와 regenerator-runtime 을 디펜던시로 갖는다. 자동적으로 babel-runtime/regenerator 와 babel-runtime/core-js 를 내장하게 되며 트랜스파일링 과정에서 인라인 Babel 헬퍼들을 제거하고 babel-runtime/helper 들을 사용하도록 변경하게 된다.

 

babel-plugin-transform-runtime 플러그인을 사용하려면 디펜던시는 아래의 두 가지 모두가 필요하다.

# babel-plugin-transform-runtime 디펜던시 추가
$ npm
install --save-dev babel-plugin-transform-runtime

# babel-runtime 디펜던시 추가
$ npm
install --save babel-runtime

babel-plugin-transform-runtime 은 트랜스파일링 과정에서 헬퍼들을 babel-runtime 모듈이 참조하도록 변경해주는 역할을 하고, babel-runtime 은 실제 실행 환경에서 헬퍼함수들이 참조할 수 있는 폴리필을 내장한 모듈로서 동작한다.

babel-plugin-transform-runtime 을 설정하는건 웹팩 기준으로는 webpack config 에서 babel 의 plugins 에 추가해주기만 하면 된다. 웹팩 설정 파일은 1.x 버전 기준이다. 웹팩 2.x 버전부터는 IE8 지원을 하지 않기 때문에 IE8 지원을 위해 폴리필이 필요한 상황이라면 웹팩 1.x 버전을 사용하는 것이 좀더 안전할 것으로 보인다. (웹팩 2.x 이상 버전도 IE8 에서 동작하기는 하는 것 같다)

loaders: [
   
//Babel 변환
    {
        test:
/\.(js|jsx)$/,
        include: [
           
/src\/js/,
           
/node_modules\/axios/
        ],
        loader:
'babel',
        query: {
            cacheDirectory:
true,

//plugins는 presets 보다 먼저 실행되며,
           
//plugins내의 순서는 처음 -> 나중으로 실행된다.
            plugins: [
               
// ['transform-class-properties'],
               
// ['transform-object-rest-spread', { useBuiltIns: true }],
                [
'transform-runtime'],
            ],
           
           
//presets내의 순서는 나중 -> 처음으로 실행된다.
            presets: [
                [
'env', {
                    targets: {
                        browsers: [
'ie >= 8']
                    },
                    loose:
true,
                }],
               
// ['react'],
            ],
        }
    },

...
],

앞서 설명한 것처럼 babel-plugin-transform-runtime 플러그인은 plugins 항목에 transform-runtime 을 추가해주는 것만으로 충분하다.

 

그 외에 주목해서 볼 부분은, include 로 node_modules 아래에 위치한 axios 를 추가해준 부분이다. 보통 트랜스파일링 대상에서 node_modules 아래에 있는 모듈들은 제외하는 것이 상식이다. 그런데 왜 추가해줬을까? 

axios 는 내부적으로 Promise 를 사용하는 라이브러리인데 Promise 가 전역 레벨에 선언되어 있지 않으면 오류가 발생하게 된다. 앞서 설명한 것처럼 babel-plugin-transform-runtime 플러그인은 전역 레벨에 폴리필을 적용하는 방식이 아니기 때문에 axios 가 실행될 때 Promise 를 찾지 못해 오류가 발생하게 되는 것이다. 이런 오류를 막기 위해 axios 도 babel-plugin-transform-runtime 플러그인을 통해 트랜스파일링 될 수 있도록 include를 사용해서 트랜스파일링 대상으로 추가해주어야 하는 것이다. 이런 부분이 babel-plugin-transform-runtime 플러그인을 사용할 때 주의할 부분이다.

 

babel-plugin-transform-runtime 플러그인은 아래와 같이 추가적인 옵션을 지정해줄 수 있으나 대부분 기본값으로 충분하다.

["transform-runtime", {
   
"helpers": true, // 인라인 바벨 헬퍼 (classCallCheck, extends, 등)을 moduleName. 으로 치환
   
"polyfill": true, // Promise, Set, Map 과 같은 새로운 내장 객체를 전역 오염없이 내부 객체를 참조하도록 변환
   
"regenerator": true, // generator 함수를 전역 오염없이 regenerator runtime 을 사용하도록 변환
   
"moduleName": "babel-runtime" // 헬퍼를 가져올 때 사용할 모듈의 이름
}]

 

 

 

babel-plugin-transform-runtime 플러그인이 적용된 코드

아래와 같은 간단한 코드를 babel-plugin-transform-runtime 을 사용하면 어떻게 트랜스파일링 될까?

class Person {
}

 

앞서 설명한 것처럼 babel-plugin-transform-runtime 은 트랜스파일링 과정에서 헬퍼들을 babel-runtime 모듈이 참조하도록 변경해주는 역할을 하고, babel-runtime 은 실제 실행 환경에서 헬퍼함수들이 참조할 수 있는 폴리필을 내장한 모듈로서 동작하게 된다.

"use strict";

var _classCallCheck2 = require("babel-runtime/helpers/classCallCheck");

var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var Person = function Person() {
  (
0, _classCallCheck3.default)(this, Person);
};

 

babel-plugin-transform-runtime 을 사용하게 되면 트랜스파일링이 필요한 부분이 너무 많을 경우 용량이 증가할 수 있으나 대체적으로 babel-polyfill 을 사용할 떄보다는 용량이 줄어든다.

하지만 babel-polyfill 과 달리 최신 브라우저에 관계없이 폴리필 코드가 무조건 물려서 동작하기 때문에 더 느려질 수 있다.

 

 

 

babel-plugin-transform-runtime 사용 시 주의할 점

그리고 치명적인 단점이 있는데, Object.assign 처럼 내장 객체의 static 메서드는 사용가능하지만, 새롭게 추가된 인스턴스 메서드 예를들면, [1,2,3,4,5].includes(3) 과 같은 메서드는 트랜스파일링 되지 않기 때문에 오류가 발생한다. 따라서 새롭게 추가된 프로토타입 메서드들은 사용하지 않도록 주의해야 한다.

또 한가지 주의할 점은 디펜던시들의 ES2015 기능들 사용 여부이다. babel-polyfill 은 전역을 직접 수정하기 때문에 npm 을 통해 설치한 디펜던시들이 Promise 와 같은 새로운 내장 객체를 사용하는지 여부를 걱정할 필요가 없지만, babel-plugin-transform-runtime 을 사용하면 이 부분까지 고려해주어야 한다. 예를들어 내부적으로 Promise 를 사용하는 디펀덴시가 있다면 이 디펜던시도 함께 트랜스 파일링 될 수 있도록 바벨 설정을 추가해주어야 한다. 앞의 예시에서는 axios 가 Promise 를 사용하기 때문에 include 로 트랜스파일링 대상에 추가해주었었다.

이런 불편함이 있지만, 전역을 오염시키지 않기 때문에 라이브러리 형태로 동작하는 경우 babel-polyfill 보다는 babel-plugin-transform-runtime 을 사용하는게 바람직하다. 내 라이브러리가 사용될 곳에서 이미 babel-polyfill 을 쓰고 있을 수도 있기 때문이다.

 

 

 

babel-plugin-transform-runtime 과 IE8

babel-plugin-transform-runtime 을 사용해서 IE8을 지원하려면, babel 은 기본적으로 ES5 환경이라고 가정하므로 core-js 의 es5 polyfill 은 필수적으로 필요하다. 앞서 core-js 가 여러번 호출될 경우 오류가 발생한다고 했었는데, 다행히 core-js 의 ES5 폴리필은 여러번 호출되어도 오류가 발생하지 않는다.

import 'core-js/es5';

babel 설정은 앞서 살펴본 것처럼 ES2015+ 관련 프리셋의 loose 모드를 활성화하고, transform-runtime 플러그인을 추가해주면 된다. 여기에서는 바벨의 env 프리셋으로 ES2015 관련 프리셋들을 추가해주고 있다. loose 모드를 활성화하지 않으면 IE8 과 호환성이 없는 코드로 트랜스파일링 되므로 주의해야 한다.

loaders: [
   
//Babel 변환
    {
        test:
/\.(js|jsx)$/,
        include: [
           
/src\/js/,
           
/node_modules\/axios/
        ],
        loader:
'babel',
        query: {
            cacheDirectory:
true,
            plugins: [
                [
'transform-runtime'],
            ],           
            presets: [
                [
'env', {
                    targets: {
                        browsers: [
'ie >= 8']
                    },
                    loose:
true,
                }],
            ],
        }
    },

...
],

그런데 이렇게 Babel을 사용해서 transform을 해줘도 실제로 번들링된 결과물에는 여전히 IE8 에서 오류가 발생하는 default, catch 등의 키워드에 대한 처리가 이루어지지 않는다.

그래서 한번더 최종적으로 es3ify-loader 혹은 babel-plugin-transform-es3-member-expression-literals, babel-plugin-transform-es3-property-literals 플러그인으로 트랜스파일링을 해주어야 완전하게 IE8과의 호환성을 갖추게 된다.

postLoaders: [
    {
        test:
/\.js$/,
        loader:
'es3ify-loader',
    }
]

또 uglify 를 해줄 경우 screw_ie8 옵션을 true 로 줄경우 IE8에서 오류가 발생하므로 반드시 이 옵션을 false 로 주어야 한다.

new webpack.optimize.UglifyJsPlugin({
    compressor: {
        screw_ie8:
false,
        warnings:
false
    },
    mangle: {
        screw_ie8:
false
    },
    output: {
        comments:
false,
        screw_ie8:
false
    }
}),

 

 

 

마치며

IE8 을 지원해야 하는 안타까운 상황이 꽤 오래 가고 있다. 점점 라이브러리들이 IE8 지원을 중단해가는 상황인데 국내에서도 IE8 을 지원하지 않는 상황이 빨리 오기를 기대한다. (최근 개편한 네이버 메인 페이지가 IE7을 지원하는 상황이니 언제쯤에야 그런 날이 올지 모르겠다) 

 

 

 

참조

https://babeljs.io/docs/usage/caveats/

https://babeljs.io/docs/usage/polyfill/

http://babeljs.io/docs/plugins/transform-runtime/

 BABEL, BABEL-PLUGIN-TRANSFORM-RUNTIME, BABEL-POLYFILL, ES2015, WEBPACK

 

출처: <https://programmingsummaries.tistory.com/401>

Posted by 철냄비짱
,