반응형
01. 복잡한 로직과 computed 속성
computed 속성
- 머스태시를 이용해 HTML 엘리먼트 값이 어떠헥 변경되는지 살펴보면서 필요한 연산 작업을 도움
<div id="main">
<p>원본 :"{{originMsg}}"</p>
<p>대문자로 변환 :"{{upperCaseMsg}}"</p>
<input type="text" v-model:value="upperInput" />
<h2>{{upperInput}}</h2>
<p>{{upperInputValue}}</p>
</div>
<script>
let app = new Vue({
el: "#main",
data: {
originMsg: "Hello, Vue Js",
upperInput: "hi",
},
//computed는 mustache 안에 전달값이 자바스크립트 로직 등 복잡할 때 사용
computed: {
//originMsg의 데이터 값을 모두 대문자로 변환하여 반환
//이 때 data의 값에 접근하기 위해 this 사용
upperCaseMsg: function () {
return this.originMsg.toUpperCase();
},
upperInputValue: function () {
return this.upperInput.toUpperCase();
},
},
});
</script>
02. 이벤트 핸들러 로직과 method 속성
method 속성
- 이벤트 핸들러를 사용해 마우스 클릭과 같은 이벤트가 발생했을 때 실행되는 로직에 활용
- 메서드는 뷰 인스턴스에 포함해 사용하는 함수를 의미
computed 속성과 method 속성의 차이점
computed 속성
- 머스태시에 작성할 로직이 복잡하면 함수로 정의할 때
- 계산량이 많아 캐시가 필요할 때
methods속성
- 뷰의 이벤트 핸들러 로직을 함수로 정의할 때
<div id="main2">
<p>클릭숫자 : {{nClick}}</p>
<p>카운트 다운 : {{fnCounter}}</p>
<!-- 버튼을 누르면 fnIncrement 메서드 실행 -->
<button v-on:click="fnIncrement">CLICK</button>
</div>
<script>
new Vue({
el: "#main2",
data: {
nClick: 0,
},
//메서드는 이벤트핸들러 로직을 실행할 때 사용
methods: {
fnIncrement() {
if (this.fnCounter === 0) {
return null;
} else {
this.nClick++;
}
},
},
//computed는 mustache 안에 로직이 복잡할 때 사용
computed: {
fnCounter() {
//nClick값이 10을 기준으로 거꾸로 카운트 되도록 하나 감소시킴
return 10 - this.nClick;
},
},
});
</script>
03. 컴포넌트로 HTML 엘리먼트 만들기
컴포넌트(component)란?
- 뷰의 중요한 특징 중 하나이며 HTML의 기본 엘리먼트 외에 자신만의 엘리먼트를 만들어 쓰는 모듈을 의미
- 미리 만든 컴포넌트 이름을 가지고 여는 태그(<>)와 닫는 태그(</>)에 적용해 사용
템플릿(template)이란?
- 새로운 엘리먼트처럼 사용할 수 있도록 컴포넌트를 등록할 때 HTML과 뷰 코드로 작성된 소스를 의미
템플릿 속성
- 컴포넌트 안에서 화면에 표시될 부분을 처리하는 속성
- HTML, CSS, 자바스크립트를 적용하여 표시될 내용의 구조와 표현, 사요자와의 상화작용 기능을 구현
- 백틱(`)키를 사용하여 문자열을 선언하면 줄바꿈이 있어도 HTML문서로 자동으로 인식
<div id="main3">
<h1>{{sTitle}}</h1>
<favorite-fruits></favorite-fruits>
<favorite-fruits></favorite-fruits>
<favorite-fruits></favorite-fruits>
</div>
//좋아하는 과일 3개를 표시하는 컴포넌트 정의
Vue.component("favorite-fruits", {
// 데이터는 fruits의 배열에 3개의 과일명을 반환하는 함수로 정의
data: function () {
return {
fruits: [
{fruit_name: "사과"},
{fruit_name: "포도"},
{fruit_name: "딸기"},
],
};
},
// 템플릿은 화면에 표시할 엘리먼트 구조 정의
template: `
<div class="fruit_style">
<div v-for="item in fruits">
<p> 좋아하는 과일 :{{item.fruit_name}}</p>
</div>
</div>
`,
});
new Vue({
el: "#main3",
data: {
sTitle: "Hello",
},
});
04. 컴포넌트 속성 props
컴포넌트 속성(props)
- 컴포넌트에서 전달되는 어트리뷰트의 값으로써, 문자열이나 객체의 배열 형식을 사용
- <componet props="value"> </component>
뷰의 컴포넌트 장점
- HTML의 일반 엘리먼트처럼 사용할 수 있기 때문에 기능을 무한대로 확장할 수 있는 잠재력
- 다양한 주제별로 그에 맞는 엘리먼트를 설계하여 사용
- 컴팩트한 개발이 가능하므로 유지보수 관점에서도 편리
<div id="app">
<h1>{{sTitle}}</h1>
<ol>
<!-- favorite-fruits 신규 엘리먼트 사용
fruits 배열의 값을 반복문으로 가져와 fruit 속성에 바인딩하여 컴포넌트에 전달 key 속성은 반드시 고유한 값으로 전달되어야 하믕로 item의 값 id값 대입 -->
<favorite-fruits
v-for="(item,index) in fruits"
v-bind:fruit="item"
:key="item.text"
>
</favorite-fruits>
</ol>
</div>
<script>
//Vue 인스턴스에 신규 엘리먼트 컴포넌트 등록
//props에 엘리먼트에 사용될 속성 이름선언
//tempalte에 전달받은 속성 객체의 text 값을 렌더링에 활용
Vue.component("favorite-fruits", {
props: ["fruit"],
template: `<li>{{fruit.text}}</li>`,
});
new Vue({
el: "#app",
data: {
sTitle: "Favorite fruits",
//컴포넌트에 표시할 과일 데이터 정의
fruits: [
{id: 0, text: "사과"},
{id: 1, text: "배"},
{id: 2, text: "복숭아"},
],
},
});
</script>
05.상태 관리와 Vuex
Vuex란?
- 뷰의 코어 중 상태 관리를 위한 패터 & 라이브러리
- 하나의 뷰 또는 복수의 화면 사이에서 여러 개의 컴포넌트를 사용하게 되면 각 컴포넌트 간에 상태값 전달이나 공유 (컴포넌트 간 공유할 수 있는 데이터 관리)
- localStorage에 저장되지 않고 메모리에 저장되므로 새로고침 시 데이터 초기화
- 상태를 새로고침 하더라도 데이터를 유지하기 위해서는 별도의 라이브러리 필요
Vuex의 작동 원리 이해하기
- State, Mutations, Getters, Actions 4개의 속성
- State : 공유한 상태값 데이터 정의
- Mutations : setter의 의미, 외부에서 동기 방식으로 저장할 때 사용
- Getters : state의 데이터 값을 외부에서 읽어 올 때 사용
- Actions : 외부의 API 실행 같은 비동기 실행을 관리할 때 사용
<div id="app">
<h1>안녕하세요</h1>
<!-- 카운터 신규 엘림너트 2개 사용. msg 속성에 이름만 다르게 적용 -->
<com-counter msg="count1"></com-counter>
<com-counter msg="count2"></com-counter>
</div>
<script>
//Vuex의 store 중앙에 state,mutaions(setters), getters, actions을 정의함
const store = new Vuex.Store({
//count 값을 상탱 값으로 정의
state: {
count: 0,
},
//mutations는 getters의 대칭되는 setters의 역할을 설정
// 데이터 변경
mutations: {
fnIncData: function (state) {
return state.count++;
}, //화샃표 함수를 활용해 count 상태값을 감소하도록 정의
fnDecData: (state) => {
state.count--;
},
},
getters: {
//상태값을 반환함
fnGetData(state) {
return state.count;
},
},
actions: {
//외부데이터 사용도 여기서 할것이다.
//상태값을 감소시키는 함수를 서버단에서 실행한다고 가정
//비동기 실행을 위해 async를 사용하고 매개변수로 commit객체 전달
async fnDecData({commit}, state) {
//가상으로 마든 원격 api 실행}
const result = await api.fnDecrement();
//원격 api가 성공할 경웨 비로소 fnDerData 함수 실행
if (result == true) commit("fnDecData");
},
},
//타이머를 사용해 1초 후 true값을 반환하도록 가상 원격 서버 API 정의
});
const api = {
//외부데이터의 모습 예졔
fnDecrement() {
//비동기 계산을 수행하기 위해 Promise를 사용하고 그에 따른 성공값을 반환하기 위해 resolve 함수 실행
return new Promise((resolve) => {
setTimeout(() => {
resolve(true);
}, 0);
});
},
};
Vue.component("com-counter", {
//카운터 제목은 엘리먼트의 msg 속성값을 받아서 렌더링 함
props: ["msg"],
template: `
<div>
<h2>{{msg}}</h2>
<p>카운터 : {{fnGetCount}}</p>
<button type="button" @click='fnIncCount'>+ 1증가</button>
<button type="button" @click='fnDecCount'> - 1 감소(원격 Api 실행)</button>
<hr/>
</div>
`,
computed: {
//카운터 값은 store에서 getters에 접근하여 값을 가져온 후 렌더링 함
fnGetCount() {
return store.getters.fnGetData;
},
},
methods: {
//카운터 증가는 동기실행을 가정하고 직접 store의 mutations에 접근 하여 실행
fnIncCount() {
store.commit("fnIncData");
},
//카운터 감소는 원격 서버 API로 비동기 실행을 가정하고 actions에 접근하여 실행
fnDecCount() {
store.dispatch("fnDecData");
},
},
});
const app = new Vue({
el: "#app",
//store 사용을 선언함
store,
});
</script>
728x90
'VueJS > VueJS' 카테고리의 다른 글
2023/06/19__VueJS(Vue && PWA && Firebase) (0) | 2023.06.20 |
---|---|
2023/06/15__VueJS(vuetify) (0) | 2023.06.15 |
2023/06/14__VueJS(Vuetify) (0) | 2023.06.14 |
2023/06/13__VueJS(router) (0) | 2023.06.13 |
2023/06/09__Vue.js (0) | 2023.06.09 |