컴포넌트(Component)란 프로그래밍에 있어 재사용이 가능한 각각의 독립된 모듈을 뜻한다.
그림에서 확인 할 수 있듯이 컴포넌트 기반 프로그래밍을 하면 마치 레고 블록처럼 이미 만들어진 컴포넌들을 조합하여 화면을 구성할 수 있다.
웹 컴포넌트는 이러한 컴포넌트 기반 프로그래밍을 웹에서도 적용할 수 있도록 W3C에서 새로 정한 규격이다. 웹 표준을 기반으로 구축되었으며, 최신 부라우저 및 모든 JavaScript 라이브러리, 프레임워크에서도 사용할 수 있다.
따라서 웹 컴포넌트를 이용하여 코드를 작성하면 Vue.js 나 React.js 와 같은 라이브러리, 프레임워크에 의존하지 않고 상호 운용이 가능하게끔 작성할 수 있다.
동작이 독립적으로 돌아가기 위한 생각을 한다
->
컴포넌트가 잘 나눠져있으면, 유지보수하기가 쉬워진다
todo list를 화면에 띄우기 위하여, todolist.html을 기준으로, todolist.js,과 이를 띄워주기 위한 todoform.js을 이용하여
다음과 같은 화면을 만들어 보겠다!
화면을 만들때,
todolist.js과 이를 띄워주기 위한 todoform.js을 이용하여 todolist가 todoform안에서 조작되고(서로가 영향을 받는다), main.js에서 헤더와 같이 객체를 만들어 만든다면, 이는컴포넌트 방식이라고 할수 없다.!
물론 구현이 되었다면 제대로 동작 하겠지만, 기능 확장 및 추가, 등 유지보수가 쉽지 않을 것이다.
이렇게 todo list 들을 화면에 띄우기 위해
todolist.js과 todoform.js, header.js, main.js, 마지막으로 app에 필요한 구성을 모아놓은 app.js 를따로 이용하여, 서로가 영향을 주지 않도록
독립적으로 구현하는 것이다,
const data=[{
text='블로그 작성하기'
},
{
text='프로그래머스 문제풀기'
}]
const $app = document.querySelector('.app')
//app컴포넌트들이 어디에 들어갈지
new App({
$target: $app,
initialState:data
})
function App({$target,initialState}){
new Header({
$target,
text:'Simple Todo list'
})
new TodoForm({
$target,
onSubmit:(text)=>{
const nextState = [...todoList.state,{
text
}];
todoList.setState(nextState)
//로컬스토리지에 추가
storage.setItem('todos',JSON.stringify(nextState))
}
})
const todoList=new TodoList({
$target,
initialState
})
}
function Header({ $target, text}){
const $header = document.createElement('h1')
$target.appendChild($header)
this.render=()=>{
$header.textContent=text
}
this.render()
}
function TodoForm({$target,onSubmit}){
const $form = document.createElement('form')
$target.appendChild($form)
let isInit =false
this.render = ()=>{
$form.innerHTML = `
<input type="text" name="todo"/>
<button>Add</button>
`
//이벤트를 해야한다.
if(!isInit){
$form.addEventListener('submit',e=>{
e.preventDefault()//태그의 기본동작을 끈다
const $todo=$form.querySelector('input[name=todo]')
const text=$todo.value
if(text.length>1){
$todo.value=''
onSubmit(text);
}
$todo.value=''
})
isInit=true
}
}
this.render()
}
// params.$target - 해당 컴포넌트가 추가가 도리 dom 엘리먼트
// params.initialState - 해당 컴토넌트 초기상태
function TodoList({$target, initialState}){
//$는 돔객체를 포함하고있는 변수다.
//todoListElement로 대체가능
const $todoList=document.createElement('div');//일종의 컨테이너?컴포넌트의 돔.
this.state = initialState;
this.setState=nextState=>{
this.state=nextState
this.render()
}//현재의 상태를 nextstate로바꾸고 render를 다시 호출한다
//const $target = params.$target;//타켓에 돔에 잘 넘겨준다.
$target.appendChild($todoList);
this.render=()=>{//컴포넌트를 그린다.
//this.state =[{text: '자바스크립트 공부하기'}.{text:'....'}]
// map을 돈 이후에는 아래처럼 만들어진다.
//['<li>자바스크립트 공부하기</li>', '<li>....</li>']
//join('')을 하면
//'<li>자바스크립트 공부하기</li><li>....</li>'
$todoList.innerHTML = `
<ul>
${this.state.map(({text}) =>`<li>${text}</li>`).join('')}
<ul>`
}
this.render();//컴포넌트를 생성한거를 실행
}
앞서 구현한 방법으로는, 새로고침을 하면 add했던 데이터들이 다 날아 간다. 따라서 기억을 해 놓는 방법이 필요하다. 여기선 두가지 방식을 소개 하겠다.
쿠키는 브라우정 저장되는 작은 문자열로
rfc 6265 명세에서 정의한 http프로토콜의 일부
다른 저장 방법에 비해 오래된 방식
cookie추가하기
document.cookie=language=javascript
덮어쓰지않고 새로추가함
쿠키 읽어 오기
const cookies = document.cookie
각 쿠키는 ;로 구분되어 있어 불러온 후 split 등으로 쪼개서 써야 한다.
cookie 유효기간 넣기
ex)오늘하루 보지않기, 1주일간 보지 않기 등
document.cookie - 'user=cho; expire=fri, 18 Aug 2021 16:19:38 GMT'
우리 나라 시간 기준이 아니라서, 시간을 받아와야 한다.
new Date().toGMTString()
cookie 사용시 주의사항
window.localStroage.name='cho' window.localStroage['name']='cho' window.localStroage.setItem('name','cho') // key value값 string이기 때문에 숫자를 넣어도 string이고 배열도 string으로 바꿔서 넣어야 한다
이 있지만, setItem을 이용해 사용하는것이 권장된다.
왜? property를 수정하는 식으로 하면 length, toString 같은 내장 함수들을 덮어 씌울 수 있기 때문이다.
const user ={
name:'cho;,
position:'centerforward'
team:['fc seoul ']
}
localStrorage.setItem('user', JSON.stringfy(user))//제작
//불러오기
const stordName=JSON.parse(localStrorage.getItem('name'))
localstroge에는 string만 넣을 수 있기 때문에
json.strignfy로 넣고 json.parse로 꺼내야 한다.
안하면 object라고 뜬다!!
전체적으로 local Storage와 같다.
딱하나 다른건,
브라우저를 닫으면 저장된 내용이 날라간다.
ex)임시값들이 필요할때, api 세싱같은것이 있다!!
상황에 따라 로컬 세션을 골라라!
const initialState=JSON.parse(localStorage.getItem('todos')|| '[]')
storage.js
일반적으로 main.js에 localStorage를 이용해서 사용해도 되지만, 직접적으로 구현을 하는것이 더 안전하다.
이는 여러가지 이유가있는데,
외부 툴 등을 이용해 todos json string을 올바르지 않은 형태로 바뀌면 어떻게될까??
=>실행이 안된다.
storage.js를 만들고 여기서만 local에 접근하도록 만드는것이 안전하다.!
storage.js
const storage =(function(storage){
const setItem =(key, value)=>{
try{
storage.setItem(key,value)
}
catch(e){
console.log(e)
}
}
const getItem = (key, defaultvalue)=>{
try{
const storedValue=storage.getItem(key)
if(storedValue){
return JSON.parse(storedValue)
}
return defaultvalue
}catch(e){
console.log(e)
return defaultvalue
}
}
return{
setItem,
getItem
}
})(window.localStorage)
이렇게 되면, main.js와 app.js가 아래와 같이 된다.
function App({$target,initialState}){
new Header({
$target,
text:'Simple Todo list'
})
new TodoForm({
$target,
onSubmit:(text)=>{
const nextState = [...todoList.state,{
text
}];
todoList.setState(nextState)
//로컬스토리지에 추가
storage.setItem('todos',JSON.stringify(nextState))
}
})
const todoList=new TodoList({
$target,
initialState
})
}
//const initialState=JSON.parse(localStorage.getItem('todos')|| '[]')
const initialState=storage.getItem('todos',[])
//새로고침하면 삭제되므로, local storage에서 꺼내게 합시다!
//일단은 잘동작하지만 위험하다.
//외부 툴 등을 이용해 todos json string을 올바르지 않은 형태로 바뀌면 어떻게될까용?
//실행이 안된다.
//storage.js를 만들고 여기서만 local에 접근하도록 만든다.
const $app = document.querySelector('.app')
//app컴포넌트들이 어디에 들어갈지
new App({
$target: $app,
initialState//:data
})
// setTimeout(()=>{
// todoList.setState([{
// text:'happy',
// }])
// },5000)
//todolist라는 변수로 받고 이걸 테스트함
local storage에 잘들어간 것을 볼수 있다.!
설계 할때 컴포넌트를 잘 이용, 및 장점
로컬스토리지의 실 사용
코어근육(기본기)를 다지는게 얼마나 중요함
물론 아직 프레임 워크를 써보진 않아서 크게 와닿는것은 아니지만, 강의내용중 프레임워크에 영향을 받지 않을 정도라니 기본기를 더욱더 잘 쌓아 유연한 개발자가 되어야 겠다.
이론으로만 배웠던 스토리지를 써본 후..
확 와닿았다. 쿠키와 세션도 직접 한번 구현해서 써봐야겠다는 생각과
함께... 끝!