[Vue] Vue Component 통신 | JS Module | Vue CLI 실행환경 구축
1. Vue Component 통신
- props : 부모 > 자식
- emit : 자식 > 부모
2. JS Module
3. Vue CLI
4. Vue SFC
5. Vue Router -> 다음 포스팅
1. Vue Component 통신
- 컴포넌트는 트리구조로 되어있다. 상하관계(부모-자식)
- 통신도 부모와 자식 간에 한다. (자식과 자식끼리 잘 안 함. 부모를 거쳐서 한다!)
- Pass Props : 부모는 자식에게 데이터 전달 (아래로↓)
- Emit Event : 자식은 부모에게 일어난 일 알림 (위로↑)
(1) 부모 → 자식
- 부모가 가진 데이터를 자식에게 내려주고, 자식은 데이터를 수정하면 안 됨. 만약 수정하고자 하면 부모에게 Emit Event로 알려주고 부모가 반영해서 다시 데이터를 내려줘야 함
- 즉, 하위 컴포넌트는 상위 컴포넌트의 값을 직접 참조 불가(값 변경X) → 데이터의 일관성/안전성 유지를 위해서
props
- 부모의 데이터를 받기위해서 사용(부모가 내려주는 이름propsdata과 동일해야 함)
- 여러 개를 받을 수 있기에 배열형태로 받음
- Vue Style Guide에서는 propsdata가 무엇인지 모르므로 적어도 타입을 명시하는 걸 권장함
ⓛ 1개의 데이터 내려보내기 (정적바인딩, 동적바인딩)
<div id="app">
<h2>부모컴포넌트</h2>
<!-- 정적 props -->
<child-view propsdata="정적인 메시지"></child-view>
<!-- 동적 props -->
<input type="text" v-model="msg">
<child-view :propsdata="msg"></child-view>
</div>
<template id="child-view">
<div>
<h3>자식컴포넌트</h3>
<div>{{ propsdata }}</div> <!-- 자식은 이 값을 변경불가 -->
</div>
</template>
<script>// 부모가 propsdata 라는 이름으로 내려준다
Vue.component('child-view', {
template: '#child-view',
props:[
'propsdata'
]
})
// app이 Root 부모, child-view가 자식
const app = new Vue({
el: '#app',
data() {
return {
msg: ''
}
}
})
</script>
- <input>은 부모컴포넌트에 존재.
- 동적바인딩(:propsdata)해줌으로써 입력 바뀔 때마다 자식컴포넌트에게 알려줘서 값이 따라서 바뀌는 것 (자식은 값 변경 불가!)
Dynamic Props
- v-bind 사용해 부모 데이터에 props를 동적바인딩 가능
- 부모의 데이터 바뀌면 그걸 참조하고 있는 자식은 알아서 바뀜
② 여러 개의 데이터 내려보내기
<div id="app">
<h2>부모컴포넌트</h2>
<child-view v-for="area in areas" :area2="area" :msg="msg[parseInt(Math.random()*5)]"></child-view>
</div>
<template id="child-view">
<div>
<h3> {{ area2 }} 지역 컴포넌트</h3>
<div>{{ msg }}</div>
</div>
</template>
<script>
Vue.component('child-view', {
template: '#child-view',
props:[
'area2', 'msg' // 부모가 area2 msg 라는 이름으로 내려보내준다
]
})
const app = new Vue({
el: '#app',
data(){
return {
areas : ['서울', '대전', '광주', '구미', '부울경'],
msg: ['lee', 'han', 'kim', 'song', 'chu']
}
}
})
</script>
③ 객체도 내려보낼 수 있다.
단방향 데이터 흐름
- 모든 props는 단방향바인딩(상위 → 하위로)
- 상위 속성이 업데이트 되면 하위로 흐르게 되지만 반대로는 안 됨
- 상위 컴포넌트가 업데이트 될 때마다 자동으로 하위 컴포넌트의 모든 prop들이 최신 값으로 갱신된다
(2) 자식 → 부모
created : 부모에게 귀를 단다..
자식컴포넌트에서 부모컴포넌트에게 발생시키는 일이 많음
사용자 정의 이벤트
- 컴포넌트 및 props완 달리, 이벤트는 자동 대소문자 변환 불가
- DOM 템플릿의 v-on 이벤트 리스너는 항상 자동으로 소문자 변환 (v-on:myEvent → v-on:myevent)
- 따라서 이벤트이름은 케밥케이스로 작성하자!
$on(eventName) : 이벤트 수신 (v-on이나 @을 통해서)
$emit(eventName) : 이벤트 발생, 추가 인자는 리스너의 콜백 함수로 전달
// 이벤트 수신
<child v-on:이벤트명="부모 컴포넌트 메서드명"></child>
// 이벤트 발생
this.$emit("이벤트명");
2. JS Module
- 프로그램을 기능별로 여러 개의 파일로 나누는 형태
watch: 연산자 값이 바뀔 때 알아서 계산을 다시 해준다.
3. Vue CLI
- JS는 브라우저 안에서만 사용할 수 있음. 브라우저마다 JS엔진 이름이 다르기 때문에. NodeJS는 크롬이 쓰고있는 V8이라는 환경을 브라우저 바깥으로 갖고 나옴.(Ryan)
- 실행환경 구축
(1) https://nodejs.org/ko/ 18버전 설치
(2) @vue/cli 설치
npm install -g @vue/cli
(3) @vue/cli 프로젝트 생성 (v2로 선택)
바벨과 웹팩을 @vue/cli 가 자동으로 쓰고 있다.
Babel : 최신코드를 과거버전으로 바꿔주는 번역기 역할
Webpack : 오픈소스 자바스크립트 모듈 번들러(모듈 간 의존성 문제 해결 cf. 스프링부트와 비슷한 역할)
vue create <project-name>
vue create vue-first-app
cd vue-first-app
- 하면 [master] 생김 → 알아서 git이 관리. (gitignore : git push 할 때 제외할 파일. node_modules는 용량이 너무 크니까)
vue add router
- 추후에 node_modules 지워도 package.json에 설치환경 다 적혀있어서 npm install 하면 다시 세팅됨
(4) 프로젝트 실행
- 이제부터는 lite-server를 사용하지 않고 cli환경에서 만들었다.
- 서버종료는 ctrl+c
npm run serve
4. Vue SFC (Single File Component)
- 확장자가 .vue 인 파일
- template + script + style = .vue (HTML, CSS, JavaScript 코드를 하나의 파일에서 관리)