Web UI는 MVVM(Model-View_ViewModel)
을 이용해서 만들어 집니다.
다음과 같은 형태라고 할 수 있습니다.
여기서 우리가 배우는 Vue.JS는 크게 두가지 일을 해주는데
이밴트가 발생하면 처리해주는 event listner
특정 Data를 HTML에 전달해주는 Data Binding기능
을 하고 있습니다.
컴퍼넌트는 트리구조로 이루어져 있습니다.
Root Component를 생성하게 되면 그 밑에 있는 여러 Component는 모두 Root Component의 하위 Component가 될 것입니다.
Contents라는 Component가 Nav를 기준으로 한다면
Contents Component는 Nav의 상위 Component가 될 것입니다.
Root Component는 포함하고 있는 모든 Compnent의 상위 Component이고,
하위 Component는 서로의 위치 기준에 따라, 상위 Component가 될 수 도 있고, 하위 Component가 될 수 도 있습니다.
Component는 전역 컴포넌트(Global Component)
와 지역 컴포넌트(Local Component)
로 나뉠 수 있습니다.
컴포넌트로 만들 객체를 생성합니다.
let cmp = {
template: "<div>여기는 DIV입니다</div>",
};
전역 Component는 다음과 같이 만들 수 있습니다.
Vue.component("child-component", cmp)
Local Component(지역 컴퍼넌트)
지역 Component는 다음과 같이 만들 수 있습니다.
<div id="app"></div>
// app이라는 id를 가진 태그에 Vue Instance를 생성하여
// Root Instance로 등록합니다.
new Vue({
el: "#app",
data: {
myID: "나용철",
myAge: 20,
},
components: {
"my-local-component": cmp,
},
});
let cmp = {
template: "<div> 지역 component: {{ cmp1Data }}</div>",
data: function () {
return {
cmp1Data: 100,
};
},
};
Component는 재사용을 목적으로 만드는 것이기 때문에 여러 곳에서 사용할 수 있습니다.
그래서 data 속성은 함수로 표현해 줍니다.
그렇지 않으면 Data의 reference가 같아져 Data의 공유 위험이 있기 때문입니다.
각각의 Component는 각각의 나누어진 값을 가지고 있어야 합니다.
11:00~11:45
<body>
<!--루트 컴퍼넌트-->
<div id="app">
<my-component1></my-component1>
<my-component2></my-component2>
</div>
<script>
// 지역 컴퍼넌트 2개를 만들어서 사용해 보아요!
let cmp1 = {
template: "<div>첫번째 지역 component: {{ cmp1Data }}</div>",
data: function () {
return {
cmp1Data: 100,
};
},
};
let cmp2 = {
template: "<div>두번째 지역 component: {{ cmp2Data }}</div>",
data: function () {
return {
// 두번째 컴퍼넌트는 첫번째 컴퍼넌트의 data를 사용하고 싶어요...!
cmp2Data: cmp1.data().cmp1Data,
};
},
};
new Vue({
//
el: "#app",
components: {
"my-component1": cmp1,
"my-component2": cmp2,
},
});
</script>
</body>
component의 data는 scope가 각 component로 한정되요!
그래서 하나의 component에서 다른 component의 data를 직접적으로
access할 수 없어요
사용할 수 있는 방법은 Vue가 제공해줘요
Vue로부터 제공받은 몇가지 방법을 알아볼게요
<div id="app">
<child-component v-bind:props-data="message"></child-component>
<!-- message의 값을 보내요 propsData에 v-bind라는 기능을 이용해서-->
</div>
<script>
// 1. 컴포넌트 하나를 전역 컴포넌트로 등록하고,
let globalCmp = {
data: function () {
return { myData: 100 };
},
};
Vue.component("child-component", {
// props 사용방법 1.
// props를 이용해서 상위 컴포넌트가 전달하는 데이터를 받는 변수를 선언해요!
// 변수는 카멜케이스를 사용합니다.
// props: ["popsData"], // 배열이 옵니다, 배열 안에는 문자열 형태로 변수명이 온다구요!
// props 사용방법 2. 권장 - 데이터 타입까지 적어서 더 자세하기 때문이에요
props: {
propsData: String, // Value 값은 데이터타입을 나타내는 생성자 함수
secondData: Number,
},
template:
"<div>자식 컴포넌트, 하위 컴포넌트, 글로벌 컴포넌트 data : {{ propsData }}</div>",
});
// 2. Vue instance에 하위 컴포넌트로 해당 컴포넌트를 포함시킬 꺼에요
new Vue({
el: "#app",
data: {
message: "맛있는 이천쌀",
},
});
// Vue instance가 상위 component가 되고
// 포함되는 전역 컴포넌트는 하위 component가 될꺼에요
// 상위 컴퍼넌트와 하위 컴퍼넌트 관계일 때 props로 data를 전달할 수 있어요
// Vue instance의 data를 전역 component에게 전달할 수 있어요
</script>
<div id="app">
<child-component v-on:print_msg="printText"></child-component>
</div>
<script>
Vue.component("child-component", {
template: "<button v-on:click='childFunc'>클릭</button>",
// 이 함수 찾아서 호출해! // 해당 함수는 상위 component가 가지고 있으면 되겠죵
// () 들어오면 return 받아서 오니까 안됨!
data() {
return { myData: 200 };
},
methods: {
childFunc: function () {
// emit는 이벤트를 발생시켜요
this.$emit("print_msg", 100, "Hello", {
msg: "전달된 이벤트",
});
},
},
});
//
new Vue({
el: "#app",
methods: {
printText: function (...args) {
console.log("이벤트 발생");
console.log(args[0]);
console.log(args[1]);
console.log(args[2].msg);
},
},
});
</script>
<div id="app">
<child-component></child-component>
</div>
<script>
// EventBus를 이용하기 위해서 Vue instance를 생성
let eventBus = new Vue(); // vue Instance 그냥 객체고
// 하위 component로 사용할 전역 component를 등록해보아요!
Vue.component("child-component", {
template: '<button v-on:click="btnClick">클릭클릭</button>',
methods: {
btnClick: function () {
// eventBus에 대해서 event를 발생시켜요!
eventBus.$emit("generateEvent", 300);
},
},
});
// Root Component
new Vue({
el: "#app",
created: function () {
// eventBus에 대해서 이벤트를 등록해 놓아요!
eventBus.$on("generateEvent", function (value) {
console.log("이벤트 발생!!", value);
});
},
});
</script>