HTML에 기반을 둔 커스텀 엘리먼트인 컴포넌트를 제작하고 활용
컴포넌트의 상탯값 관리와 뷰 간의 이동을 도와주는 Vuex와 라우터제공
05-1 복잡한 로직과 computed 속성
computed 속성 : 머스태시를 이용해 HTML 엘리먼트값 변경에 따른 연산 작업지원
- 원본 data를 수정으로 필요성 확인
* 010501 [DoIt!실습] 대문자로 변환하는 프로그램 만들기
- 0105/ex05_01 > computed.html 파일 생성
<!DOCTYPE html>
<html lang="KO">
<head>
<meta charset="UTF-8">
<title>computed</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
</head>
<body>
<div id="main">
<p>원본 문장 : "{{ sOriginalMessage }}"</p>
<p>대분자로 변환된 문장 : "{{ fnUpperCaseMsg }}"</p>
</div>
<script>
new Vue({
el:'#main',
// data는 머스태시 안에 넣을 값이 간달할 때 사용
data:{
sOriginalMessage: 'How are you?'
},
computed:{
// sOriginalMessage의 데이터를 모두 대문자로 변환
// 이때 데이터에 접근하기 위해 this 사용
fnUpperCaseMsg: function(){
return this.sOriginalMessage.toUpperCase();
}
}
})
</script>
</body>
</html>
* 머스태시 사용 : 문자열을 {{}} 로 감싸고 엘리먼트(P) 값 표시
- {{ sOriginalMessage }} : 문자열 변수 대체
- {{ fnUpperCaseMsg }} : 함수실행결과 대체
* data 속성
- 문자열 변수(sOriginalMessage - 속성 : JSON 형식내 값 > 뷰에서는 변수처럼 처리됨) 값 초기화
* computed 속성 : computed 속성은 캐시 메모리에 저장 - 속도개선 효과 기대
- 머스태시 내용이 복잡한 경우 함수로 전환하여 사용
- fnUpperCaseMsg() 함수에서 this를 사용하여 data에 정의된 변수(sOriginalMessage)를 사용하여 처리함
05-2 이벤트 핸들러 로직과 methods 속성
* 메서드 : 뷰 인스턴스에 포함해 사용하는함수
- methods 속성 : 이벤트 핸들러를 사용해 이벤트 실행로직 작성(마우스 클릭 등)
- 예제 : 버튼을 누를 때마다 10부터 거꾸로 세는 예제
> computed 속성 : 머스태시 확장할 때 사용
> methods 속성 : 이벤트 핸들러에 사용
* 010502 [DoIt!실습] 카운트다운 프로그램 만들기
- 0105/ex05_02 > computed.html 파일 생성
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>mothods</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
</head>
<body>
<div id="main">
<p>클릭 숫자 : {{nClicks}}</p>
<p>카운트다운 : {{fnCounter}}</p>
<!-- 버튼을 누르면 fnIncrement 메서드 실행 -->
<button v-on:click="fnIncrement">눌러주세요!</button>
</div>
</body>
<script>
new Vue({
el:'#main',
data:{
nClicks:0
},
// computed는 머스태시 안의 로직이 복잡할 때 사용
computed: {
fnCounter(){
// nClicks 값이 10을 기준으로 카운트다운 되도록 1만큼 감소시킴
return 10 - this.nClicks;
}
},
// 메서드는 이벤트 핸들러 로직을 실행할 때 사용
methods:{
// nClicks 값을 1만큼 증가시킴
fnIncrement(){
this.nClicks++;
}
}
});
</script>
</html>
* 머스태시적용
- nClicks : 클릭개수 정보 변수를 바인딩 - 엘리먼트(p)
- fnCounter() : 카운트로 변경되는 값 반환 - 10부터 시작하는 카운트다운 처리
* v-on 디렉티브 적용
- 버튼을 누르면 fnlncrement() 함수를 이벤트 핸들러로 연결하여 실행
> fnlncrement() 함수의 구체적인 기능을 methods 속성에서 정의한다
* data, computed 속성
- data : nClicks 변수 초기값 설정 - 0
- computed : 머스태시 선언 함수 기술 - fnCounter()
> fnCounter() 함수는 10을 기준으로 지금까지 클릭한 횟수를 저장
> nClicks 변수값과 뺄셈을 수행
* 머스태시에 선언된 내용의 로직이 복갑해지면 함수로 바꿔서 computed 속성에 정의
* methods 속성
- fnlncrement() 함수 : nClicks 변수(클릭한 횟수 저장) 값을 ++ 연산자로 증가시킨 후 반환
> data 속성에 정의된 nClicks 변수에 접근하기 위 해 this를 사용
* [하나만 더 배워요!] computed 속성과 methods 속성의 차이점
- 함수 정의 시 두 속성의 역할 : 함수 실행
• computed 속성 : 복잡한 로직으로 머스태시 작업을 함수로 정의 - 계산량이 많아 캐시가 필요할 때
• methods 속성 : 뷰의 이벤트 핸들러 로직을 함수로 정의
05-3 컴포넌트로 HTML 엘리먼트 만들기
* 컴포넌트(component) : HTML의 기본 엘리먼트 외에 자신만의 엘리먼트 제작 지원
* 컴포넌트의 동작 원리 이해하기
- 컴포넌트 사용법 : HTML 엘리 먼트와 동일. 여는 태그 <>, 닫는 태그 </>에 적용해 사용
> <my-element></my-element>
- 템플릿(template) : 컴포넌트를 등록하여 엘리먼트처럼 사용
- 컴포넌트를 신규 엘리먼트로 구성 시 화면에 표시할 부분을 대응하는 속성 : 템플릿 속성
> 기존 HTML, CSS, 자바스크립트를 사용해서 화면에 표시할 내용 구현
> 사용 방법 : [template:] 속성 선언 > 문자열로 HTML 문서의 내용을 작성
** 문자열 줄바꿈을 고려한 이스케이프 문자 사용 : 역따음표(',backtic-백틱) - 예제 참고
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>component</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
</head>
<body>
<div id="main">
<my-element></my-element>
</div>
</body>
<script>
// my-element 엘리멘트용 컴포넌트 등록
Vue.component('my-element',{
// 컴포넌트의 data 속성은 반드시 함수로 정의!
data: function(){
return {
strHello: '안녕하세요',
}
},
// 템플릿은 화면에 표시할 엘리멘트 구조를 정의
template: `<h1>{{strHello}}</h1>`
});
new Vue({
el:'#main',
});
</script>
</html>
* 010503 [DoIt!실습] 좋아하는 과일 나열하기
- 0105/ex05_03 > component_basic.html 파일 생성
- 화면에 표시할 내용 : template 속성으로 HTML, CSS, 자바스크립트를 함께 사용하면서 작성
- 백틱을 사용한 가독성 확보
> 예제 활용 : template, data 속성만 사용하지 만 computed, methods 속성도 활용
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>component_basic</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<style>
.fruit_style {/* 테두리 스타일과 안쪽 여백을 넣어줌*/
border: 1px solid #ccc;
background-color: #fff;
padding-left: 1em;
}
</style>
</head>
<body>
<div id="main">
<h1>{{ sTitle }}</h1>
<!-- 신규 컴포넌트 엘리먼트 2개 사용 -->
<favorite-fruits></favorite-fruits>
<favorite-fruits></favorite-fruits>
</div>
</body>
<script>
// 좋아하는 과일 3개를 표시하는 컴포넌트 정의
Vue.component('favorite-fruits',{
// 컴포넌트의 data 속성은 반드시 함수로 정의
data: function(){
return {
aFruits:[{sFruit_name:'사과'}, {sFruit_name:'오렌지'},{sFruit_name:'수박'}]
}
},
// 컴포넌트 템플릿 화면에 표시할 엘리먼트 구조 정의
template:`
<div>
<div v-for="item in aFruits" class="fruit_style">
<p>좋아하는 과일:{{item.sFruit_name}}</p>
</div><br>
</div>`
});
new Vue({
el:'#main',
data:{
sTitle:'안녕하세요!'
}
});
</script>
</html>
* 박스 스타일
- 화면에 표시할 영역을 눈으로 쉽게 확인하기 위해 CSS 스타일 적용
- [.fruit_ style]이라는 클래스 선택자로 경계선 구성
> 선 : 직선, 두께 : 1px, 색상 : #ccc(회색) 설정
> 배경색 : 흰색
* 컴포넌트 사용
- sTitle(제목 문자열) 변수 : h1 엘리먼트의 값으로 표시.
- h1 엘리먼트 : HTML5 예약어는 커스텀 불가
- favorite-fruits 커스텀 엘리먼트 : HTML 엘리먼트와 같은 방식으로 사용
> 좋아하는과일 세 가지 목록을 표시
> 두 번 연속 사용 : 두 번 표시됨
* 컴포넌트 등록 - 뷰 객체의 component() 함수를 사용해 엘리먼트 등록
- 매개변수1 : [favorite-fruits] 전달
- 매개변수2 : [data, template] 속성 정의
> data 속성 : aFruits 배열을 JSON 형식으로 정의 - 변수나 함수로 선언
> aFruits 배열 : sFruit_name, 과일 이름(사과, 오렌지, 수박) 항목 3개 구성
- function() 함수에서 return 문으로 반환
** 컴포넌트에서 data 속성을 사용할 때는 반드시 함수로 사용
- 컴포넌트 안에 data 속성을 변 수로 선언하면 실행 시 인스턴스가 생성되지 않음
> ‘ReferenceError: aFruits is not defined’라는 오류 발생
- 같은 컴포넌트를 여러 개 사용 시, data 속성의 변숫값들이 별도의 메모리 공간에서 개별적으로 관리되도록 하려는 의도
- 따라서 컴포 넌트 내부는 반드시 함수로 작성해야 합니 다.
* 컴포넌트 템플릿 작성
- div 엘리먼트로 그룹
- v-for 디렉티브를 사용해서 aFruits 배열 변수에 있는 항목을 하나씩 꺼내서 표시
- p 엘리먼트에 머스태시로 바인딩하기 위해 {{ item.sFriiit_name }} 입력
> 항목이 3개 표시, fruit_ style 클래스 선택자로 스타일 적용
* [하나만 더 배워요!] 목록의 구조를 잡을 때 사용하는 ul, ol, li 엘리먼트
- ul(unordered list)과 ol(ordered list) : 목록 영역 결정
> ul : 순서 없는 목록 - 글머리 기호 항목 앞에 표시
- li(list) : 목록의 각 항목 표시
> ol : 순서 있는 목록 - 항목 앞에 번호가 하나씩 커지면서 표시
<!-- ul, ol, li 엘리먼트사용 예 -->
<ul>
<li>사과 </li> <li> 바나나 </li> <li> 수박 </li>
</ul>
<ol>
<li> 커피 </li> <li> 홍차 </li> <li> 녹차 </li>
</ol>
05-4 컴포넌트 속성 props
* 컴포넌트 속성(props) : 컴포넌트에서 전달되는 어트리뷰트의 값
- 문자열, 객체 배열 형식
> 좋아하는과일 나열 예제 변경 : 컴포넌트 엘리먼트로 props 속성 사용
* 010504 [DoIt!실습] 컴포넌트 속성을 활용해 좋아하는 과일 나열하기
- 0105/ex05_04 > component_prop.html 파일 생성
* 뷰 컴포넌트의 어트리뷰트를 선언하는 방법, 값을 전달받아 사용하는 방법 확인
- 뷰의 컴포넌트 기능은 HTML의 일반엘리먼트처럼 사용할 수 있으므로 기능을 무한대로 확장가능
> 다양한 주제별로 그에 맞는 엘리먼트 설계해서 사용
> 의미있는 컴포넌트 엘리먼트 이름으로 심플코드 개발 가능(어트리뷰트 설계 유의) : 유지보수 용이
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>component_prop</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<script>
// Vue 인스턴스에 신규 엘리먼트 컴포넌트 등록
// props에 엘리먼트에 사용될 속서 이름 선언
// template에 전달받은 속성 객체의 text 제목을 렌더링에 활용
Vue.component('favorite-fruits', {
props: ['fruit'],
template:`<li>{{ fruit.text }}</li>`
})
</script>
</head>
<body>
<div id="app">
<h1>좋아하는 과일!</h1>
<ol>
<!--
favorite-fruits 신규 엘리먼트 사용
aFruits 배열의 값을 반복문으로 가져와 fruit 속성에 바인딩하여 컴포넌트에 전달
key 속성은 반드시 고유한 값으로 전달되어야 하므로 item의 id값 대입
-->
<favorite-fruits
v-for="item in aFruits"
v-bind:fruit="item"
v-bind:key="item.id">
</favorite-fruits>
</ol>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
aFruits:[
{id:0, text: '사과'}
, {id:1, text: '오렌지'}
, {id:2, text: '수박'}
]
}
});
</script>
</body>
</html>
* 컴포넌트등록
- 컴포넌트 : HTML 엘리먼트와 동일하게 사용 - 어트리뷰트 사용가능
> props 속성 선언
- 선언된 이름을 다른 속성에서 전달받아 매개변수처럼 사용
* 컴포넌트 등록 (이름 : favorite-fruits)
- props 속성에 대괄호([])를 사용해서 어트리뷰트 이름을 문자열로 선언
> HTML에서 favorite-fruits 엘리먼트를 사용할 때 다음과 같이 fruit 어트리뷰트에 값 전달
<favorite-fruits fruit="사과"></favorite-fruits>
* template 속성에 li 엘리먼트로 속성값 표시
- 머스태시로 <li>{{ fruit.text }}</li> 작성 : li 엘리먼 트값으로 바인딩
> 속성값으로 전달받은 fruit 변수는 text 속성으로 전달
> 유의 : props 속성에 선언하여 어트리뷰트로 전달받은 fruit 변수 : 일반 변수처럼 사용가능
* 컴포넌트사용
- favorite-fruits 컴포넌트를 등록 > 일반적인 HTML 엘리먼트처럼 사용
> 소스에서는 먼저 ol로 순서 있는 목록의 영역 지정
- 목록의 개별 항목은 li 엘리먼트 대신에 favorite-fruits 엘리먼트 사용
> favorite-fruits 엘리먼트 : 내부적으로 li 엘리 먼트를 가지 면서 전달받은 속성값을 표시하도록 설계
- 신규로 등록한 컴포넌트의 엘리 먼트에 어트리뷰트를 어 떻게 사용하는지 잘 표현
- v-for 디렉티브도 사용가능 : aFruits 배열 변수에서 값을 꺼내 item에 하나씩 저장
- v-bind 디렉티브를 사용해서 fruit 어트리뷰트에 바인딩하여 항목값을 전달
> v-bind:key 바인딩은 v-for 디렉티브를 사용할 때는 key 어트리뷰트에 고유한 값 전달해 사용하도록 강제
> item.id의 값을 전달하면 간단히 해결
* data 속성
- aFruits 배열 변수 : data 속성에 정의
> JSON 형태로 id와 text에 번호와 과일 이름을 저장
05-5 상탯값 관리와 Vuex
05-5 상탯값 관리와 Vuex
05-6 내비게이션과 라우터
05-7 새로 고침이 필요 없는 SPA 만들기
'book > PWA만들기' 카테고리의 다른 글
[2nd].04 뷰 기초 쌓기 (0) | 2023.05.09 |
---|---|
[1st].03 순수 자바스크립트로 PWA 만들기 (2) | 2023.05.09 |
[1st].02장 모던 자바스크립트 꼭 필요한 것만 배우기 (1) | 2023.03.28 |
[1st].01장 헬로! 프로그레시브 웹앱 (4) | 2023.01.25 |
프로그레시브웹앱만들기 - intro (0) | 2023.01.25 |