I. 수업 방향관련
수업방향성 관련
Vue -> 옵션즈 api 와 컴포지션 api 두가지가 있어
Exception
Dao -> 를 mybatis 를 쓰는데, 대비되는것이 JPA야!
Security -> BackendSecurity VS FrontedSecurity(on Vue)
Dom -> Component (에디터 / 탐색기/ 드랍박스 / 모달 / ...)
등을 우리가 한다
이 중에서 일단 Vue.js -> compositionAPI 를 이용해서 한다.
II. Composition API 대두
1. Composition API vs Options API
(1) 들어가며
1) 탄생배경
Single file component(SFC) 나오면서 대두한것이 컴포지션이야 그래서 배타적인것은 옵션즈 API야!
옵션즈는 2.대 버전 인거고, 향후에는 옵션즈가 유지될거야
2) SFC의 이유
main.js 는 js 파일인데, 여기다가 vue를 import 하면 가능해 (최종코드는 아님) 보다 자유롭게!
에컨데 vue 파일에다가 싱글파일로 뷰,자바스크립트, 스타일 3가지 영역을 순서 상관없이 하나의 파일로 둘 수있다
js 파일로 번들하면서 자동으로 합쳐준다는 의미이다
결국 SFC의 장점으로 귀결됨 하나의 파일로 하고 node.JS와 결합할 때 용이함
3) Composition API 의 필요성 : options API 의 문제점
<script>
export default{ //사용한 객체 반환위해서!
data(){
return {
a:10
};
}
}
</script>
중괄호가 중첩되었다는것은 객체가 3개 중첩되었다는거야!
옵션은 중괄호 방식으로 지속적으로한다
코드는 중첩이많으면 좋은코드다???
<script>
export default{ //사용한 객체 반환위해서!
data(){
return {
a:10
};
}
}
</script>
//===
<template>
hello {{ a }}
</template>
10이 출력돼!
III. Composition API vs Options API 차이점
1. 차이점 : 기존의 문법 : 값 바인딩
그러면 이제 컴포지션 방식을 해보자!
(1) one way binding
1) 출력하는 방법
중괄호 중첩3개짜리가 없어져버려
<script>
export default{ //사용한 객체 반환위해서!
data(){
return {
a:10
};
}
}
</script>
<!-- 컴포지션 방식! -->
<script setup>
let b = 30;
</script>
<template>
hello {{ a }}
hello {{ b }}
</template>
<style>
</style>
이렇게 손쉽게 b값에다가 값을 넣을 수 가 있다!
2) 방법
<script setup> 를 이용하면 쓸 수있다.
(2) two way binding : 값
1) one-way / two-way
컴포지션API
reactivity(반응형) -> 2way 를 지원하느냐의 문제야
2) 컴포지션 API는 2way binding 바로 가능한지
<script>
export default{ //사용한 객체 반환위해서!
data(){
return {
a:10
};
}
}
</script>
<!-- 컴포지션 방식! -->
<script setup>
let b = 30;
</script>
<template>
<div>
hello {{ a }}
hello {{ b }}
</div>
<div>
a:<span v-text="a"></span><input v-model="a"/><br>
b:<span v-text="b"></span><input v-model="b"/>
</div>
</template>
컴포지션은 기본적으로 1way 는 되는데, 2way는 지원할 수 있을까?
a의 경우 2way (옵션즈api) 방식이다
위 이미지와 같이 a반 가능하다.
3) 컴포지션의 2way 바인딩 방법
그렇다면 ref()를 써보자
<script setup>
let b = ref(30);
</script>
하지만 아무것도 출력이 되지않는다. 화이트스페이스만 출력이 된다.
<!-- 컴포지션 방식! -->
<script setup>
import {ref} from 'vue';
let b = ref(30);
</script>
ref 객체를 vue 에서 import 를 하면 된다
이런것과 같이 옵션스api 보다 훨씬 수월하다
(3) two way binding : 객체
1) ref() 방식으로 2way binding 만들기
그렇다면 객체에 대해서도 해보자
<script setup>
import {ref} from 'vue';
let b = ref(30);
let menu = ref({
id : 1,
name : "아메리카노",
price : 3000
});
</script>
<template>
<div>
hello {{ a }}
hello {{ b }}
</div>
<div>
a:<span v-text="a"></span><input v-model="a"/><br>
b:<span v-text="b"></span><input v-model="b"/><br>
price : <span v-text="menu.price"></span><input v-model="menu.price"><br>
</div>
</template>
여기서도 마찬가지로
menu 객체에 대해서 ref() 를붙였는지 여부에 따라 2way 지원여부가 달라진다.
2) 문제점
그런데 ref() 는 값이지, 객체 전용은 아니야
이런경우 쓸 수 있는것이 reactive() 를 쓰면 돼!
<script setup>
import {ref} from 'vue';
let b = ref(30);
let menu = reactive({
id : 1,
name : "아메리카노",
price : 3000
});
</script>
이렇게 하면 객체도 2way 바인딩이 가능하다.
2. 차이점2 : 템플릿 붙이는 방식 차이
(1) options API
1) header.vue 만들기
이러한 상단에 header 에 대한 결과를 만들고 싶다
파일을 만들어준다.
<script>
import { Header } from './components/header.vue';
export default{ //사용한 객체 반환위해서!
data(){
components:{
Header
},
return {
a:10
};
}
}
</script>
options API 는 이렇게 불편해
즉 import 후에 이에 대해서 components 안에다가 직접 다 넣어주어야해
(2) Composition API
1) 컴포지션 방식
그런데 컴포지션은 다음과 같이 이용이가능해
<script setup>
import {reactive, ref} from 'vue';
import Header from './components/header.vue';
let b = ref(30);
let menu = reactive({
id : 1,
name : "아메리카노",
price : 3000
});
</script>
그냥 import 만 해주고나서 <template> 부분에다가 <Header /> 만 해주면 돼
3. 차이점3 : 생명주기 차이
(1) options API
1) mount() 방법
<script>
export default{ //사용한 객체 반환위해서!
data(){
// components:{
// Header
// },
return {
a:10
};
},
mounted() {
console.log("mounted");
},
}
</script>
여기서는 mount() 를 expot{} 해주는 중괄호 안에 결국 속해야한다.
(2) Composition API
<!-- 컴포지션 방식! -->
<script setup>
import {onMounted,reactive, ref} from 'vue';
import Header from './components/header.vue';
//-------------------
let b = ref(30);
let menu = reactive({
id : 1,
name : "아메리카노",
price : 3000
});
//-------------------
onMounted(() => {
console.log("mounted11");
console.log(`b:${b}`);
console.log(`menu.price :${menu.price}`);
});
</script>
onMointed() 를 하면 바로 이용이 가능해!
이렇듯 생명주기 방식도 더 간소화 됐어
4. 차이점4 : 메소드
(1) options API
<script>
// import { Header } from './components/header.vue';
export default{ //사용한 객체 반환위해서!
data(){
// components:{
// Header
// },
return {
a:10
};
},
mounted() {
console.log("mounted");
},
//여전히 중첩이 심하다!
methods:{
clickHandler(){
console.log("click");
}
}
computed :{
total(){
return this.a + 2;
}
}
}
</script>
methods 객체에서 clickHander() 를 해주면된다.
중첩되는 방식이여서 불편하다.
(2) Composition API
1) 구현방법
<!-- 컴포지션 방식! -->
<script setup>
import {onMounted,reactive, ref} from 'vue';
import Header from './components/header.vue';
//----Variables ---------------
let b = ref(30);
let menu = reactive({
id : 1,
name : "아메리카노",
price : 3000
});
//---Life Cycle----------------
onMounted(() => {
console.log("mounted11");
console.log(`b:${b}`);
console.log(`menu.price :${menu.price}`);
});
//----Event Handlers ---------------
function clickHandler(){
console.log("clock Hehe");
}
</script>
손쉽게 함수를 만들어주고 쓰면 돼!
<template>
<Header />
<div>
hello {{ a }}
hello {{ b }}
</div>
<div>
a:<span v-text="a"></span><input v-model="a"/><br>
b:<span v-text="b"></span><input v-model="b"/><br>
price : <span v-text="menu.price"></span><input v-model="menu.price"><br>
<button @click="clickHandler" >클릭버튼</button>
</div>
</template>
클릭버튼을 눌럿을 때 로그에 출력되게끔 하였다.
(3) 함수표현관련 : 람다표현식을 쓰는 경우
1) 람다표현식의 방향성
그렇다면 화살표 함수 방식(람다 표현식)으로 하는게 바람직할까?
코드를 보면 코드가 보이는가 함수가 보이는가?
function clickHandler(){
console.log("clock Hehe");
}
const clickHandler = () =>{
console.log("clocked hehe");
}
람다는 수식을 쉽게 표현하기 위한 최소한의 함수구조였어
즉 수식을 전달하는데 불필요한 껍대기가 눈에 띄지 않기를 바라는것이 화살표 함수야!
가급적 람다식을 지양하자!
5. API 데이터를 받아서 화면에 바인딩 시켜주기
(1) 화면에 데이터 출력하기
1) fetch API 방식으로 데이터 받기
let model = reactive({
newList : [],
list : []
});
//---Life Cycle----------------
onMounted(() => {
console.log("mounted11");
console.log(`b:${b}`);
console.log(`menu.price :${menu.price}`);
});
//----Event Handlers ---------------
//await 와 함께하는 async
async function load(){
//과거에는 then 했는데, 지금은 awiat
let response = await fetch("http://192.168.0.33:8080/menus");
let json = await response.json();
//리액티브한상태로 보내줌
model.list = json.list;
// console.log(list);
}
function clickHandler(){
console.log("clock Hehe");
// console.log(list);
load();
// console.log(list);
}
이렇게 하면 된다
fetch then 방식보다 하나씩 값을 넣어주는 방식이 가독성 관점에서 좋을 수있다.
그런데 이러한 값을 list에 담아주어야하는데 그냥 담을 수는없다.
특정 버튼을 눌렀을 때 반응으로 브라우저에 출력되어야한다.
이런경우는 앞서 배웠던것 처럼 reactvie 를 써야한다. 이것을 이용해서 model 처럼 사용이가능해
reactvie 그 자체가 아니라 속성으로 바꾸는 방식을 해야해
2) load()로 별도로 함수로 만들어 준 이유
그리고 앞서 load() 해서 불러온 이유는 mount 에도 호출하기 위해서야
onMounted(() => {
console.log("mounted11");
console.log(`b:${b}`);
console.log(`menu.price :${menu.price}`);
load();
});
이렇게 mount 될 때 load() 를 하면 바로 화면에 바인딩이 가능해!
3) 컴포지션 필요성 공감의 중요성
이렇게 컴포지션 방식의 필요성을 느끼자!!
6. render 함수
(1) render 함수의 의의
1) 의의
render 함수를 이용 html 에 대해서 직접객체를 만드는 작업을 할 수 있어
아래 템플릿부분을 위 render() 로 바꿀 수있는거야! 보통 화면렌더링 방식을 이렇게 하는거야
이렇게 가상 DOM 을 해주는거야!
7. 차이점 5 : computed 함수
(1) 의의
그냥 함수가 아닌 함수를 직접 만드는 것이다
기존의 값을 계산하고 연산하는 방식이야 계산된 녀석으로 볼 수 있어
(2) options API
옵션스 api 방식
1) 선언방법
<script>
// import { Header } from './components/header.vue';
export default{ //사용한 객체 반환위해서!
data(){
// components:{
// Header
// },
return {
a:10
};
},
// mounted() {
// console.log("mounted");
// },
//여전히 중첩이 심하다!
// methods:{
// clickHandler(){
// console.log("click");
// }
// }
computed :{
total(){
return this.a + 2;
}
}
}
</script>
앞서 다른 방식과 마찬가지로 객체를 만들고 그 안에서 total() 함수를 만들어주는 방식이다
2) 값을 연산하기 위한 number
<div>
a:<span v-text="a"></span><input v-model.number="a"/><br>
b:<span v-text="b"></span><input v-model="b"/><br>
price : <span v-text="menu.price"></span><input v-model="menu.price"><br>
<button @click="clickHandler" >클릭버튼</button>
</div>
parseInt 를 안쓰기 위해서 .number를 이용한다
(2) 람다식의 용도
1) 용도의 이해
지역변수 선언해서 역할 필요하면 function을 쓰고, 필요없으면 lamda를 써
식이 중요한경우 람다 애로우평선 쓰고, 지역변수 쓰는등 덕지덕지면 함수를 써야해!!!
let total = computed(() => 3 + 1); //이렇게 쓰면 computed 의 매력을 느낄 수있어
(3) composition API
1) 컴포지션 하에서 computed() 알아보기
<script setup>
import {onMounted,reactive, ref, computed} from 'vue';
import Header from './components/header.vue';
//----Variables ---------------
let b = ref(30);
let menu = reactive({
id : 1,
name : "아메리카노",
price : 3000
});
let model = reactive({
newList : [],
list : []
});
let total = computed(() => b.value + 3); //이렇게 쓰면 computed 의 매력을 느낄 수있어
//---Life Cycle----------------
onMounted(() => {
console.log("mounted11");
console.log(`b:${b.value}`);
console.log(`menu.price :${menu.price}`);
load();
});
<script/>
computed () 를 쓰면 돼 이 경우 +3 을 하면 되는건데
ref() 때문에 b.value + 3 을 해주면 된다.!
2) computed() 이용하기
메뉴 목록의 값도 바꾸어보자 예컨데 장바구니 가격을 바꿀 수 있는 기회이다
let total = computed(() => {
let result = 0;
for(let m of model.list){
result += m.price;
}
return result;
}); //람다로 쓰면 computed 의 매력을 느낄 수있어
(4) render 를 이용한 구현
reduce() 를써보고 싶지?
그러면 map 을 쓰고 reduec() 를 써보자~!
<script setup>
import {onMounted,reactive, ref, computed} from 'vue';
import Header from './components/header.vue';
//----Variables ---------------
let b = ref(30);
let menu = reactive({
id : 1,
name : "아메리카노",
price : 3000
});
let model = reactive({
newList : [],
list : []
});
let total = computed(()=> model.list.map((m)=>m.price).reduce((p,c) => p+c, 0));
// let total = computed(() => {
// let result = 0;
// for(let m of model.list){
// result += m.price;
// }
// return result;
// }); //람다로 쓰면 computed 의 매력을 느낄 수있어
//---Life Cycle----------------
onMounted(() => {
console.log("mounted11");
console.log(`b:${b.value}`);
console.log(`menu.price :${menu.price}`);
load();
});
//----Event Handlers ---------------
//await 와 함께하는 async
async function load(){ //따로 함수를 만들어준 이유는 mount 에도 쓰기위해서야
//과거에는 then 했는데, 지금은 awiat
let response = await fetch("http://192.168.0.33:8080/menus");
let json = await response.json();
//리액티브한상태로 보내줌
model.list = json.list;
// console.log(list);
}
function clickHandler(){
console.log("clock Hehe");
// console.log(list);
load();
// console.log(list);
}
</script>
이렇게 가능해! 이런건 데이터분석에서 흔히 쓰이는 방법이야!
map() 으로 model 에 값 중 price 부분만 배열로 저장시켜줘
저장한 배열을 reduce(p+c , 0) 에서
p 즉 누적값에 c 현재 값을 지속적으로 더해주는것이다.
이 경우 0은 초기값을 의미하는거야
정리하면 초기값 0에서 시작해서 c를 더해주면서 누적값 p가 나온다.
마지막으로 p 가 반환되는 형식이야
그러면 다음과 같이 합계 액이 나온다.
1. 보충
2. 회고
1) 사실 Vue 에 대해서 번거로웠던게 optiosAPI방식이 중괄호의 연속이여서 가독성을 해치고 불편함을 야기했다
그런데, 컴포지션API를 보니 충분히 할만하겠다는 생각이 든다.
2) reduce() 라는 흥미로운 자동으로 해주는 JS 함수가 있는것이 신기하다.
'배움 __IL > TIL 1기' 카테고리의 다른 글
TIL : 100번째- 230428 [4-4-금] (0) | 2023.04.28 |
---|---|
TIL : 99번째- 230427 [4-4-목] (0) | 2023.04.27 |
TIL : 97번째- 230425 [4-4-화] (1) | 2023.04.25 |
TIL : 95번째- 230421 [4-3-금] (0) | 2023.04.21 |
TIL : 94번째- 230420 [4-3-목] (0) | 2023.04.20 |