2024. 8. 14. 17:11ㆍVue
- react custom hook
> 커스텀 hook으로 로직 재사용
- DOM/BOM
> document, window(생략가능)
- CRUD
C - createElement보다는 innerHTML을 선호한다 - DOM 구조를 몇 번이나 변경하는지
R - querySelector, querySelectorAll, closest ( 아랫쪽, 윗쪽 어디서 찾아가느냐 )
U - classList
Event 모델
- addEventListener()
- 버블링/ 캡처링
- stopPropagation/preventDefault
- EventLoop, 리스너(핸들러), 람다식
엣날 방식 = btn.addEventListener('click', function() {...}, false); 버블링( 안쪽에서 바깥쪽으로 )
> 이렇게 하면 function을 재사용하지 못한다.
>> 왜 이렇게 ?
모듈패턴 - 보통은 싱글턴 구현하기 위해서 사용했던 방식
> 클로저가 가장 많이 쓰이는 방식
>> 클로저 : 외부에 노출되지 않는 보호되는 데이터 ( 상태라고 한다 )
>>>클로저를 이용하면 어떤데이터를 개별적으로 보호할 수 있다.
>>>>이 데이터를 접근하는 함수를 하나 만든다. > 이 함수만 노출을 시킨다.> 외부에서는 노출된 함수만 사용하기 때문에 이 데이터에 직접적으로 접근하지 못하는게 클로저의 장점이다.
- 노출한다는 것 = 리턴한다 > 이것을 하는것이 클로저
> 이거랑 + 를 해서 하나를 더 한다. 즉시 실행함수
>>이 두개를 결합해주면 싱글턴의 효과가 난다.
1.sample2.js
2. index.html = src = sample2.js
모듈패턴 = 내가 원하는함수를 반환하기 위해서 사용
- 배열로 반환할때도 있다
> react useState , 배열로 반환할때도 있지만 객체를 반환할때도 있다.
- Vue3= 리액트를 많이 참고했다.
[모듈 패턴]
- 코드단위를 명확하게 분리하고 구성
- 클래스를 모방해서 관련이 있는 함수를 모아 즉시실행함수로 감싸서 하나의 모듈을 만들어 클로저 기반으로 동작한다.
- 한번 실행하면서 클로저(인스턴스변수) 인스턴스변수를 사용하는 메서드를 사용해준다. ( 자바에서 객체만들어준다 생각하면된다)
- 즉시실행함수 = 한번 만 실행가능하다
[순서도]
1. npm create vite@latest
2. 해당 폴더로 이동
3. npm install
4. index.html <script>삭제
5. 상품 product.js -> 상품 목록 반환 작업
6. 카트 -> cart.js -> 장바구니 처리
목표 > 로직 분리
7. 상품 리스트(product.js)
const list = [
{pno: 1, pname: 'Americano', price: 1500},
{pno: 2, pname: 'Latte', price: 2500},
{pno: 3, pname: 'Ice', price: 2000}
]
8. getList 노출
export const getList = () => list
9. index.html
<script type="module">
import {getList} from './product.js'
const menuList = getList()
const menuUL = document.querySelector('.menuDiv ul')
//menu하나하나를 li태그로 바꿔줄 거다.
menuUL.innerHTML =
menuList.map(menu => `<li>
<div>
${menu.pno}
${menu.pname}
${menu.price}
</div>
</li>`).join('')
</script>
10. product.js
export const findMenu = (pno) => list.find(menu=> menu.pno === pno)
11. index.html
<script type="module">
import {getList, findMenu} from './product.js'
const menuList = getList()
const menuUL = document.querySelector('.menuDiv ul')
//menu하나하나를 li태그로 바꿔줄 거다.
menuUL.innerHTML =
menuList.map(menu => `<li>
<div data-pno="${menu.pno}">
${menu.pno}
${menu.pname}
${menu.price}
</div>
</li>`).join('')
menuUL.addEventListener('click', e => {
const target = e.target
console.log(target)
const pno = target.dataset.pno//문자열로 가져온다.
const menu = findMenu( parseInt(pno) )
if (!menu) {
return
}
console.log(menu)
}, false)//false = 캡처링 안한다.
</script>
12. cart.js
상품 => {pno, pname, price}
카트 => [ {pno, pname, price, qty} ]
let cartArr = []
export function addCart(product){
//전개 연산자
cartArr.push({...product, qty:1})
}
export const getCart =()=>cartArr
13. index - 함수를 파라미터로 던진다.
<script type="module">
import {getList, findMenu} from './product.js'
import {addCart, getCart} from "./cart.js";
const menuList = getList()
//될수있으면 고정된 값에 걸어라, 동적인것에 걸지말고
const menuUL = document.querySelector('.menuDiv ul')
const cartUL = document.querySelector('.cartDiv ul')
//menu하나하나를 li태그로 바꿔줄 거다.
menuUL.innerHTML =
menuList.map(menu => `<li>
<div data-pno="${menu.pno}">
${menu.pno}
${menu.pname}
${menu.price}
</div>
</li>`).join('')
menuUL.addEventListener('click', e => {
const target = e.target
console.log(target)
const pno = target.dataset.pno//문자열로 가져온다.
const menu = findMenu(parseInt(pno))
if (!menu) {
return
}
//console.log(menu)
addCart(menu, refreshCart)
}, false)//false = 캡처링 안한다.
const refreshCart = () => {
const cartList = getCart()
cartUL.innerHTML = cartList.map(
cart => `<li>
<div data-pno=${cart.pno}>
${cart.pno}
${cart.pname}
${cart.price}
${cart.qty}
</div>
</li>`).join('')
}
</script>
14. cart.js - 던져받은 함수를 실행
let cartArr = []
export function addCart(product){
//전개 연산자
cartArr.push({...product, qty:1})
if(callback)
{
callback()
}
}
export const getCart =()=>cartArr
15. cart.js 수정
let cartArr = []
export function addCart(product, callback){
//전개 연산자
cartArr.push({...product, qty:1})
if(callback)
{
callback(cartArr)
}
}
16. index
<script type="module">
import {getList, findMenu} from './product.js'
import {addCart} from "./cart.js";
const menuList = getList()
//될수있으면 고정된 값에 걸어라, 동적인것에 걸지말고
const menuUL = document.querySelector('.menuDiv ul')
const cartUL = document.querySelector('.cartDiv ul')
//menu하나하나를 li태그로 바꿔줄 거다.
menuUL.innerHTML =
menuList.map(
menu => `<li>
<div data-pno=${menu.pno}>
${menu.pno}
${menu.pname}
${menu.price}
</div>
</li>`).join('')
menuUL.addEventListener('click', e => {
const target = e.target
console.log(target)
const pno = target.dataset.pno//문자열로 가져온다.
const menu = findMenu(parseInt(pno))
if (!menu) {
return
}
//console.log(menu)
addCart(menu, refreshCart)
}, false)//false = 캡처링 안한다.
const refreshCart = (buyItems) => {
cartUL.innerHTML = buyItems.map(
cart => `<li>
<div data-pno=${cart.pno}>
${cart.pno}
${cart.pname}
${cart.price}
${cart.qty}
</div>
</li>`).join('')
}
</script>
17. cart.js
let cartArr = []
export function addCart(product, callback) {
//이미카트안에 있었을지도 모르니까
const findproduct = cartArr.find(cart => cart.pno === product.pno)
if (findproduct) {
findproduct.qty += 1
} else {
//전개 연산자
cartArr.push({...product, qty: 1})
}
if (callback) {
callback(cartArr)
}
}
18. 버튼 추가 index
<script type="module">
import {getList, findMenu} from './product.js'
import {addCart} from "./cart.js";
const menuList = getList()
//될수있으면 고정된 값에 걸어라, 동적인것에 걸지말고
const menuUL = document.querySelector('.menuDiv ul')
const cartUL = document.querySelector('.cartDiv ul')
//menu하나하나를 li태그로 바꿔줄 거다.
menuUL.innerHTML =
menuList.map(
menu => `<li>
<div data-pno=${menu.pno}>
${menu.pno}
${menu.pname}
${menu.price}
</div>
</li>`).join('')
menuUL.addEventListener('click', e => {
const target = e.target
console.log(target)
const pno = target.dataset.pno//문자열로 가져온다.
const menu = findMenu(parseInt(pno))
if (!menu) {
return
}
//console.log(menu)
addCart(menu, refreshCart)
}, false)//false = 캡처링 안한다.
const refreshCart = (buyItems) => {
cartUL.innerHTML = buyItems.map(
cart => `<li>
<div data-pno=${cart.pno}>
${cart.pno}
${cart.pname}
${cart.price}
${cart.qty}
</div>
<div><!--추가, 몇번인지/ HTML에는 정보만 넣는다.-->
<button data-pno="${cart.pno}" data-job="plus">+</button>
<button data-pno="${cart.pno}" data-job="minus">-</button>
</div>
</li>`).join('')
}
cartUL.addEventListener("click", e=> {
const target = e.target
console.log(target)
const pno = target.dataset.pno
const job = target.dataset.job
//데이터 처리 = cart.js
}, false)
</script>
19. cart
let cartArr = []
export function addCart(product, callback) {
//이미카트안에 있었을지도 모르니까
const findproduct = cartArr.find(cart => cart.pno === product.pno)
if (findproduct) {
findproduct.qty += 1
} else {
//전개 연산자
cartArr.push({...product, qty: 1})
}
if (callback) {
callback(cartArr)
}
}
export function changeQty(pno, job, callback) {
const findproduct = cartArr.find(cart => cart.pno === pno)
if (job === 'plus')
{
findproduct.qty += 1
}
else if (job === 'minus'){
findproduct.qty -= 1
cartArr = cartArr.filter(cart => cart.qty > 0)
}
if (callback) {
callback(cartArr)
}
}
20. index
<script type="module">
import {getList, findMenu} from './product.js'
import {addCart, changeQty} from "./cart.js";
const menuList = getList()
//될수있으면 고정된 값에 걸어라, 동적인것에 걸지말고
const menuUL = document.querySelector('.menuDiv ul')
const cartUL = document.querySelector('.cartDiv ul')
//menu하나하나를 li태그로 바꿔줄 거다.
menuUL.innerHTML =
menuList.map(
menu => `<li>
<div data-pno=${menu.pno}>
${menu.pno}
${menu.pname}
${menu.price}
</div>
</li>`).join('')
menuUL.addEventListener('click', e => {
const target = e.target
console.log(target)
const pno = target.dataset.pno//문자열로 가져온다.
const menu = findMenu(parseInt(pno))
if (!menu) {
return
}
//console.log(menu)
addCart(menu, refreshCart)
}, false)//false = 캡처링 안한다.
const refreshCart = (buyItems) => {
cartUL.innerHTML = buyItems.map(
cart => `<li>
<div data-pno=${cart.pno}>
${cart.pno}
${cart.pname}
${cart.price}
${cart.qty}
${cart.price * cart.qty}
</div>
<div><!--추가, 몇번인지/ HTML에는 정보만 넣는다.-->
<button data-pno="${cart.pno}" data-job="plus">+</button>
<button data-pno="${cart.pno}" data-job="minus">-</button>
</div>
</li>`).join('')
}
cartUL.addEventListener("click", e=> {
const target = e.target
console.log(target)
const pno = target.dataset.pno
const job = target.dataset.job
//데이터 처리 = cart.js
changeQty(parseInt(pno), job, refreshCart)
}, false)
</script>
[화면 처리와 순수 로직의 분리]
- 화면쪽 작업
- 데이터를 렌더링 - 상황에 맞게
- 이벤트 처리
- JS의 복잡성이 증가 - 자바스크립트는 모아서 모듈로 빼버리면 된다. 문제점 : HTML과 JS는 같이있어야 한다.
> 이걸 뺄 수 있으면 좋겠다 > 결과적으로 필요한것
>> 화면(HTML) + 이벤트처리 + 상태 데이터 : 이렇게 하나의 단위로 구성을 해야 한다. -> Vue, React =컴포넌트
[지도 API]
카카오 디벨로퍼
앱키 : 985d15d1ee0e4a532eb93aebfb132c41
플랫폼 : web
문서화 작업
JSON으로 처리
[7!4d9
{ 가게번호: 1 , 가게이름: '가게이름', lat: 32.xxxxxx, lng:127.xxxxxx }
{ sno: 1, sname: '가게이름', lat: 32.xxxxxx, lng: 127.xxxxxx}
{ sno: 1, sname: 'funnybeer', lat: 35.150596, lng: 129.115766 }
]
- 화살표 함수를 많이 쓰는 이유 = this
- 동적인 것들은 addEventListener가 안걸린다.
> createElement를 해서 addEvenetListener를 걸 수 있다.
[axios]
- node.js와 browser를 위한 비동기 처리 클라이언트
- axios : 외부에서 데이터를 가져오는 것
- npm install axios
- 고정된 데이터, 주어진데이터 : 화면에 출력해줘야했다
- 사용자가 생성하는 데이터 : 화면에 출력 이벤트 처리 + 외부데이터
- 자바스크립트가 어려워지는 이유 : 화면출력, 이벤트처리, 외부데이터
- axios : 외부데이터를 쉽게 가져다 쓰는 라이브러리( 외부데이터 로딩하는 라이브러리 )
> URL상에 있는 데이터를 가지고 온다.(크롤링해서 데이터 쓰면안되나? > 안된다.)
>> 외부데이터 쓸때는 보안문제가 생긴다.
>>> localhost:5173을 쓸때는 맘껏 써도된다 > 문자열로 데이터를 가져왔다.
- eval > 문자열을 자바스크립트로 처리되어버린다. ( 보안상으로 위험하다 )
- axios API를 쓰는것이 서버통신에 가장 짧은 코드를 짤 수 있다.
- 기본이 JSON이다.
[ Ajax ]
1. 의도
2. 처리
- Ms가 만들었다. 왜? > 운영체제, 브라우저 > 브라우저에서 운영체제와 통신하는것을 만들고 싶었다. > ActiveX
> 로컬머신
- 브라우저가 외부리소스와 통신하기를 원했다 ( 다른 URL과 통신 )
> 처음에 나왔을때는 Ajax라는 언어이다. ( Asynchronous nc Javascript & xml )
- 이벤트와 비슷한 방식을 고려한다.
- W3C Ajax
> 과거에는 자바스크립트가 이정도로올라갈것이라고 생각하지 못했다. 순수한 데이터를 xml에 저장했었다.
- on이라는 단어가 나오면 외부 데이터를 받는것
- 비동기모델, 이벤트를 쓸 수 밖에 없었는지?
> 선행작업이 끝날 때까지 다음작업을 할 수 없기때문에 이벤트로 등록해놓으면 결과가 왔을때 이벤트 핸들러만 처리해주면 되기때문에. 이런방식의 코딩을 적용한것이 비동기프로그래밍이다.
>> 비동기 프로그래밍 : 이벤트와 같다고 보면된다.
>>>자바스크릡트는 클릭이벤트만 처리하던앤데 이제는 서버통신도 한다.
ex) IOT : device, 휴대폰, 브라우저
- 수많은 디바이스가 있는데 종류가 틀리다.
- 만약 엄청난 데이터를 가지고있고 이 데이터를 어디선가 쓰고싶다면? > 안드로이드, 애플, pc등등에서 사용하기위해선 그것에 맞게 해줘야하는데 그럼 비용이 엄청나게 든다.
- 그래서 이 데이터를 줄게 > 니가 알아서 써
> 이게 가장 돈을 쉽게 벌 수 있는 방법
- ASP, JSP > 과거의 서버는 데이터를 만들어서 보내줬다.(서버에서 화면에 만들필요가 없어졌다 요즘은)
- 하지만 요즘 시대는 데이터만 가지고 브라우저에서 처리 가능
- 그래서 서버에서는 JSon이나, XML데이터만 만들어준다.
- 이것의 몫 (마지막) 은 브라우저의 몫이다.
- 자바스크립트 promise
'Vue' 카테고리의 다른 글
[6] JS - Vue (0) | 2024.08.21 |
---|---|
[5] JS - Vue3 (2) (0) | 2024.08.20 |
[4] JavaScript (0) | 2024.08.19 |
[2] JavaScript (0) | 2024.08.13 |
[1] JavaScript (0) | 2024.08.12 |