[VUE.JS] VUE[뷰] 시작해보기





요새 프론트 엔드 라이브러리로 핫하다는 vue를 접해 보았다.


접했다는게 정말 손끝으로 살짝 건들여본 정도 ㅋㅋㅋ



얼마전 node.js 와 react.js를 하고 아주아주 기초적인 파이썬을 해보고


이번엔 vue를 건들여 본다 ㅋㅋ





react를 공부해놓고 왜 이번엔 vue 를 사용하는가 라는 물음에 대한 대답은


"그냥! 개발자라면 새로 나왔다는거 한번쯤 건들여 봐야지!"


라고 할수 있겠지만;;;



일단 문서상으론 react보다 뛰어나다고 하니 한번 해보는게 나쁘진 않을 것 같은데


스택오버플로우에서 참고할 레퍼런스들이 아주 적고


react나 angular에 비해서 실제 업무에 적용된 사례가 적기도 해서


현업에서 바로 실서비스에 적용 하는건 아직 무리라고 보고


그냥 한번쯤 해보는건 좋을 것 같다.



이번에 하는 포스팅은 뭔가 대단하게 셋팅을 하고 설정파일들을 만지작 거리는게 아니라


정말 아주 간단하게



CDN으로 불러와서 마치 제이쿼리 쓰듯 사용해 보는 것에 대해서 포스팅 해보도록 한다.







일단 뭐 프로젝트 만들 필요도 없이 맛만 볼거니까


jsBIn 이나 jsfiddle 에서 사용해 보는 것만 테스트 해보도록 하자




jsbin


https://jsbin.com/xojatohopi/edit?html,js,output





jsbin 의 기본적인 화면이다.


여기서 아주아주 간단하게


제이쿼리 집어넣듯



<script src="https://unpkg.com/vue/dist/vue.js"></script>


한줄을 추가해 주도록 하자



1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
 hello
  
  <script src="https://unpkg.com/vue/dist/vue.js"></script>
</body>
</html>
cs




이렇게 한줄을 추가 해주면


우린 vue.js 를 사용할 준비가 끝난 것이다.



그럼 이제 body 안에


간단한 문장을 써보도록 하자




.








<h1>hello, yamea</h1>


이라는 한줄을 추가 했는데


이것만 가지고는 vue의 어떤 뭘 사용하는지 모르겠다



여기서 살짝만 변형 시켜 보자



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
 
</head>
<body>
  <div id="app">
    <h1>hello, {{name}}</h1>
  </div>
  
  
  <script src="https://unpkg.com/vue/dist/vue.js"></script>
</body>
</html>
cs




이렇게 작성 하면




이렇게 나온다



이제 vue의 기능을 이용해 저 {{name}} 의 텍스트를 바꿔 보도록 하자



자바스크립트에 아래 코드를 추가 해준다



1
2
3
4
5
var app = new Vue({
  el:'#app',
  data:{name:"cheesu's yamea"}
  
});
cs




이런 스크립트 코드를 추가 해주면





짠!


이렇게 된다


마치 EL태그의 jstl 을 스크립트로 사용하는 것 같은 기분이 든다



그럼 여기서 추가로 한가지만 더 해보도록 하자



위의 콘솔 버튼을 클릭해서





app.name = "추천 눌러줘"


를 입력하고 엔터를 누르면 {{name}}의 내용이 바뀐다!





기본적인 기능은 여기까지다



아주 쉽지 않은가?


와.. 이정도면 그냥 써먹어도 되겠다


react를 처음 접할때보다 뭔가 장벽이 어마무시하게 낮아진 기분이다.


react보다 vue의 러닝커브가 훨씬 작다고 하니


간단하게 사이드 프로젝트 정도는 해볼만 한 것 같다.



나도 여기까지 밖에 안해봤으니


다음 포스팅에선 조금더 심화적인 단계로 넘어가 보도록 하자.

함수형 컴포넌트 만들기


react에서 컴포넌트를 정의할때 class 문법을 사용하는데 


라이프사이클API를 사용하거나 state를 사용하는 경우에는 class 문법을 사용해 컴포넌트를 만들어야 한다.


일반적으로 지금까지 만들어왔던


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//파일 및 컴포넌트의 첫 문자를 대문자로 하는건 React의 naming convention 입니다.
import React from 'react'//import JavaScript ES6 에 새로 도입된 키워드로서, require('..') 의 역할을 합니다.
/*
* 컴포넌트에서 immutable (변하지 않는)  데이터가 필요 할 땐,
* render() 메소드의 내부에 안에 { this.props.propsName } 형식으로 넣고,
* 컴포넌트를 사용 할 때, < > 괄호 안에 propsName="value" 를 넣어 값을 설정합니다.
*
* */
class Header extends React.Component {
    render(){
        return (
            <h1>this.props.title }</h1>
        );
    }
}
export default Header; //export는 JavaScript ES6 에 새로 도입된 키워드로서, module.export = Header 와 같습니다.
cs



이런식이다.


주석이 많아 좀 보기 힘들지만.. 주석을 지우면


1
2
3
4
5
6
7
8
9
10
11
12
13
import React from 'react'
 
class Header extends React.Component {
 
    render(){
        return (
            <h1>this.props.title }</h1>
        );
    }
 
}
 
export default Header; 
cs


이런식이 되겠다.



그런데 라이프사이클API도 사용하지 않고 state도 사용하지 않고


단순히 props만 전달해 뷰를 렌더링해주는 역할만 한다면 


함수형 컴포넌트 형식으로 컴포넌트를 정의 할 수 있다.




1
2
3
4
5
6
7
8
9
10
import React from 'react'
 
    function Header(){
        return (
            <h1>{props.title }</h1>
        );
    }
 
 
export default Header; 
cs



이런식으로 말이다.


뭔가 아까보다 단순해지지 않았는가?



여기서 ES6의 애로우펑션(화살표 함수)를 사용하여 만들 수도 있다.



1
2
3
4
5
6
7
8
9
10
import React from 'react'
 
    const Header = (props) => {
        return (
            <h1>{ props.title }</h1>
        );
    }
 
 
export default Header; 
cs




이 코드를 비구조화 할당 문법을 사용한다면




1
2
3
4
5
6
7
8
9
10
import React from 'react'
 
    const Header = ({title}) => {
        return (
            <h1>{ title }</h1>
        );
    }
 
 
export default Header; 
cs


이렇게 만드는게 가능 하다.



class문법을 사용하는 것 보다 훨씬 간단해 졌다.


그러나 함수형 컴포넌트에 따로 성능최적화가 이뤄진 것이 아니기 떄문에 


성능에선 클래스형 컴포넌트와 다르지 않다.


리액트 팀에서 함수형 컴포넌트의 성능을 최적화하겠다고 했지만 


일부 상황에서 제대로 동작하지 않는 오류가 있다고 하는데


레딧에서 본 정보이니 자세한 내용은 아니다.


리액트 컴포넌트 라이프 사이클 API



이 포스팅은


VELOPERT 님의 포스팅을 아주많이 참조하였습니다;;


(출처 : https://velopert.com/1130 )





1. 컴포넌트 라이프 사이클 API 순서


컴포넌트를 생성 할 때는 


constructor -> componentWillMount -> render -> componentDidMount 


순으로 진행됩니다.


컴포넌트를 제거 할 때는 componentWillUnmount 메소드만 실행됩니다.


컴포넌트의 prop이 변경될 때엔 


componentWillReceiveProps -> shouldComponentUpdate -> 

componentWillUpdate-> render -> componentDidUpdate 


순으로 진행됩니다.


 state가 변경될 떄엔 props 를 받았을 때 와 비슷하지만 shouldComponentUpdate 부터 시작됩니다.


그림으론 아래와 같이 보시면 됩니다.





2. 각 메소드들이 하는 역할


1) constructor

3
4
constructor(props){
    super(props);
    console.log("constructor");
}

1
2
3
4
5
6
7
8
9
10
11
12
13
  constructor(props) {
        console.log("컨텍트 생성자 시작");
        super(props);
        this.state = {
            contactData: [
                {name: "Abet", phone: "010-0000-00035"},
                {name: "Betty", phone: "010-0000-0002"},
                {name: "Charlie", phone: "010-0000-0003"},
                {name: "David", phone: "010-0000-0004"}
            ]
        };
        console.log("컨텍트 생성자 끝");
    }
cs


-> 생성자 메소드 입니다. 컴포넌트가 처음 만들어질때 실행되며 이곳에서 기본 state를 정할 수 있습니다.




2) componentWillMount

componentWillMount(){
    console.log("componentWillMount");
}


-> 컴포넌트가 DOM 위에 만들어지기 전에 실행 됩니다.





3) render

1
2
3
4
5
6
7
render() {
        return (
            <button onClick={this.handleClick.bind(this)}>
                Remove selected contact
            </button>
        );
    }
cs

-> 컴포넌트 렌더링을 담당합니다.



4) componentDidMount

componentDidMount(){
    console.log("componentDidMount");
}


-> 컴포넌트가 만들어지고 첫 렌더링을 다 마친 후 실행되는 메소드 입니다.

이 안에서 다른 JS 프레임워크를 연동하거나. setTomeout, setInterval및 Ajax 처리를 넣습니다.

--> https://medium.com/@taeho.leon.kim/javascript-%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC%EB%93%A4%EC%97%90-%EB%8C%80%ED%95%9C-%EC%9D%B4%EC%95%BC%EA%B8%B0-8fc74fab2140#.8nmyw5gjt

이곳에서는 해당 API가 렌더링을 시잓하는 즉시 실행한다고 이야기 한다. 즉 렌더링이 끝날때까지 기다려주지 않는다고 말이다.

아직 정확히 확인을 해보지 못하였다. 





5) componentWillReceiveProps

componentWillReceiveProps(nextProps){
    console.log("componentWillReceiveProps: " + JSON.stringify(nextProps));
}


-> 컴포넌트가 prop을 새로 받았을 때 실행 됩니다. porp에 따라 state를 업데이트 해야 할 떄 사용 하면 유용 합니다.

     이 안에서 this.setState()를 해도 추가적으로 렌더링 하지 않습니다.




6) shouldComponentUpdate

2
3
4
shouldComponentUpdate(nextProps, nextState){
    console.log("shouldComponentUpdate: " + JSON.stringify(nextProps) + " " + JSON.stringify(nextState));
    return true;
}


-> 이전 포스팅에서 사용했던 메소드. prop나 state가 변경 되었을때 리렌더링을 할지 말지 정하는 메소드.

    실제로 활용 할때는 필요하는 값을 비교해서 반환하도록 사용 한다. (이전 포스팅 참조)

2017/02/27 - [Yame Programmer/react.js] - [react.js] 변경된 값만 렌더링 되도록 하기 shouldComponentUpdate()


7) componentWillUpdate

componentWillUpdate(nextProps, nextState){
    console.log("componentWillUpdate: " + JSON.stringify(nextProps) + " " + JSON.stringify(nextState));
}


-> 컴포넌트가 업데이트 되기 전에 실행된다. 이 메소드 안에서는 this.setState()를 사용하면 안된다. 무한루프에 빠져들어 버린다.



8) componentDidUpdate

2
3
componentDidUpdate(prevProps, prevState){
    console.log("componentDidUpdate: " + JSON.stringify(prevProps) + " " + JSON.stringify(prevState));
}


-> 컴포넌트가 리렌더링을 마친 후 실행된다




9) componentWillUnmount

componentWillUnmount(){
    console.log("componentWillUnmount");
}



-> 컴포넌트가 dom 에서 사라진 후 실행되는 메소드















변경된 값만 렌더링 되도록 하기 shouldComponentUpdate()


react 강좌를 보며 예제를 따라해보고 하던 도중


라이프사이클이나 실행유무 어떤 메소드가 먼저 실행되는지


여기에 있는 this와 저기에 있는 this 가 무슨 차이가 있는지


알아보기 위해 여기저기 온갖곳에 console.log를 사용하여


개발자모드 화면에서 콘솔들을 보는 도중


특정값이 바뀌는데도 맵안에 들어가 있는 녀석들을 전부 하나씩


다시 렌더링 한다는걸 알게 되었다


역시나 그에 대한 해답도 강좌에 마지막 부분에 써있었는데


기록해놔야 겠다 싶어서 포스팅을 한다



1
2
3
4
// 컴포넌트를 다시 렌더링 해야 할 지 말지 정의해준다
    shouldComponentUpdate(nextProps, nextState){
        return (JSON.stringify(nextProps) != JSON.stringify(this.props));
    }
cs




shouldComponentUpdate


요 함수가 다시 렌더링을 할지 말지 정의를 해주는데 리턴값을 보면


다음 props와 현재 props를 비교 해서 렌더링 할지 말지 정해주는 것 같다.


리턴이 true false로 가니 좀 더 다른 방법으로도 응용이 가능 할 것 같다.


ES6에는 생소한 문법들도 많고 평소 사용하던 방식과 너무나도 많이 달라 


react를 공부하는데 어려움이 엄청나게 많다. 


심지어 나는 bind나 this를 자주 사용하지 않았기 때문에 더 심한것 일수도...


현재 공부중인 리액트 예제들은


https://github.com/cheesu/react-tu


이곳에 올려놨으니 받아서 보는 것도 좋을 것이다.


왜냐하면 주석을 여기저기 엄청나게 달아놓고 console.log도 엄청나게 달아놨기 때문에 


혹여나 관심있는 사람들은 받아보면 도움이 될 것 같다.



module not found error cannot resolve 'babel' in 에러와 the node api for babel has been moved to babel-core  해결 방법




드디어 리액트에 입문!


아직 뭐가 뭔지도 잘 모르고


바벨이라는 녀석이 ES6문법으로 바꿔주고 웹팩이라는 녀석이 번들js로 


관리해준다는 대략적인 정보만 알고 난 상태에서


https://velopert.com/814


이분의 강좌를 보면서 공부를 하기로 시작 했는데 시작과 동시에 에러가 날 반겨준다.




1. the node api for babel has been moved to babel-core  해결 방법




<으아악 불길한 붉은 텍스트라니>



the node api for babel has been moved to babel-core


이 에러는 뭐 대충 설치 할때 경로 문제나 디펜던시 설정 문제 인듯 하다


pakage.json 파일의 디펜던시를 아래와 같이 바꿔주면 해결이 된다.


아마 위의 에러가 나는 것은 딘펜던시와 덴펜던시스 둘다 바벨이 들어가 있는 경우이며


글로벌로 babel과 webpack를 설치 한 후


또 종속성으로 --save 명령어로 설치하는 경우에 나타나는 에러 인듯 하다.



1
2
3
4
5
6
7
8
9
10
11
12
 "dependencies": {
    "react": "^15.4.2",
    "react-dom": "^15.4.2"
  },
  "devDependencies": {
    "babel-core": "^6.23.1",
    "babel-loader": "^6.3.2",
    "babel-preset-es2015": "^6.22.0",
    "babel-preset-react": "^6.23.0",
    "webpack": "^2.2.1",
    "webpack-dev-server": "^2.4.1"
  }
cs


디펜던시 목록을 위와같이 수정해주면 사라지며


그래도 계속 나타날 경우엔 어차피 튜토리얼 단계니까 


폴더 지우고 다시 순서대로 받아주면 해결 된다.




2.module not found error cannot resolve 'babel' in 에러 해결 방법





이 에러는 webpack.config.js 파일을 수정해 주어야 한다.


이 파일은 webpack의 설정파일인데


ECMAScript6를 컴파일 해주고 개발서버를 열어주는 webpack의 설정 파일인데


모듈 로더 부분이


1
2
3
4
5
6
7
8
9
10
11
12
13
    module: {
        loaders: [
            {
                test: /\.js$/,
                loader: 'babel',
                exclude: /node_modules/,
                query: {
                    cacheDirectory: true,
                    presets: ['es2015''react']
                }
            }
        ]
    }
cs



이런식으로 loader:'babel'

로 되어있는 경우 발생한다


바벨을 참조하지 못해서 생기는 오류인듯 한


loader:'babel' -> loader:'babel-loader' 이렇게 바꿔주면 간단히 해결이 된다.


1
2
3
4
5
6
7
8
9
10
11
12
13
   module: {
        loaders: [
            {
                test: /\.js$/,
                loader: 'babel-loader',
                exclude: /node_modules/,
                query: {
                    cacheDirectory: true,
                    presets: ['es2015''react']
                }
            }
        ]
    }
cs



이제 npm start 명령어를 실행하면 complied successfully 라는 반가운 문구를 볼 수가 있게 된다.



+ Recent posts