Life-Cycle
컴포넌트 생성부터 소멸까지
Life-Cycle Hooks
Life-Cycle 중간중간 생성 단계 이름으로 된 함수를 지칭
Hook 이름으로 함수를 선언하고 실행해보는게 이해하는데 편안함
<template>
<div>
{{ count }}
</div>
<h1>Vue.js 라이플 사이클 테스트</h1>
</template>
<script>
export default {
data() {
return {
count: 0,
};
},
beforeCreate() {
console.log("LifeCycle is beforCreate", this.count);
// this.test()
},
created() {
console.log("LifeCycle is created", this.count);
this.test();
},
// beforeMount() {
// console.log("LifeCycle is beforeMount", document.querySelector('h1'));
// },
// mounted() {
// console.log("LifeCycle is mounted", document.querySelector('h1'));
// },
methods: {
test() {
console.log('함수 호출!!')
}
},
};
</script>
<style lang="scss" scoped></style>
출력
보간법이라고 하는데 중괄호 2개 겹쳐서 사용 '{{ }}'
출력타입은 무조건 문자열
혹여나 태그를 삽입하고 싶으면 innerHTML 기능과 비슷한 것이 있음
<template>
<div>{{ rawHtml2 }}</div> // 문자열로 나옴
<div v-html="rawHtml2"></div> // innerHTML 같은 기능
</template>
<script>
export default {
data() {
return {
rawHtml2:
'<span style="color: tomato;">이것은 토마토 색이여.</span>',
}
},
};
</script>
<style scoped>
</style>
바인드
data() 리턴 값으로
- 조건문을 만들어 활성화 여부를 정할수 있음, true | false 도 물론가능
- 예시는 class인데 id도 있고 :disable 이런것도 있음
- inline style에도 속성 값으로도 사용
- 여기저기 다 쓰임
<template>
<h2 v-bind:class="{ active: isActive }">클래스 바인딩 테스트</h2>
<h2 :class="{ active: isActive }">클래스 바인딩 테스트</h2>
<button @click="change">버튼</button>
<h3 style="color: red; font-size: 24pt">스타일 바인딩 테스트</h3>
<h3 :style="{color:'#888888', fontSize: 24 + 'pt'}">스타일 바인딩 테스트</h3>
<h3 :style="{color:fontColor, fontSize: fontSize + 'pt'}">스타일 바인딩 테스트</h3>
</template>
<script>
export default {
data() {
return {
isActive: false,
fontColor: '#888888',
fontSize: 36
};
},
methods: {
change() {
this.isActive = !this.isActive;
},
},
};
</script>
<style scoped>
h2.active {
color: green;
}
</style>
조건문
태그에 속성으로 사용하면 되고
흔히 아는거하고 비슷함
- v-if="조건"
- v-else-if="조건"
- v-else
- v-show 이건 css display 속성 달고 나옴 안보이는 거지 없는건 아님
이벤트 핸들러
onclick 이런거 표시하는 방법임
- 정식 : v-on:click="실행할 함수"
- 약식 : @click="실행할 함수"
- @chagne, @checked, @keyup, ... 많겠지?
- 함수대신에 data() 여기서 넘어온 변수명 조작도 됨 count ++ 이런거
<template>
<div>
<button v-on:click="count++">인라인 핸들러</button>
<h1>{{ count }}</h1>
<br>
<button v-on:click="changeName()">메서드 핸들러</button>
//<button @click="changeName()">메서드 핸들러</button>
<h1>{{ name }}</h1>
</div>
</template>
<script>
export default {
data() {
return {
count: 0,
name: "Vue.js",
};
},
methods: {
changeName() {
this.name = "변경된 텍스트 데이터 입니다."
}
}
};
</script>
<style lang="scss" scoped></style>
for문
이것도 아는거 하고 비슷함
Jquery로 for문 돌려봤으면 한번에 이해 가능
:key는 꼭하래, 공식문서에서도 권장하네
페이지 새로고침하면 :key 확인해서 변경점이 있는 녀석만 다시 만들어 내어서 전기세 덜 내고 로딩 시간 절약 가능
<template>
<ul>
<li>{{ sampleArr[0] }}</li>
<li>{{ sampleArr[1] }}</li>
<li>{{ sampleArr[2] }}</li>
<li>{{ sampleArr[3] }}</li>
<br />
<li v-for="(item, idx) in sampleArr" :key="item" @click="openDialog(item || idx)">{{ item }} - {{ idx }}</li>
<br />
<li v-for="(item, idx) in ortherArr" :key="item.id">
{{ item.id }} / {{ item.name }} / {{ idx }}
</li>
</ul>
</template>
<script>
export default {
data() {
return {
sampleArr: ["a", "b", "c", "d"],
ortherArr: [
{ id: 0, name: "John" },
{ id: 1, name: "Kim" },
{ id: 2, name: "Han" },
{ id: 3, name: "Park" },
],
};
},
methods: {
openDialog(result) {
console.log(result);
}
}
};
</script>
<style lang="scss" scoped></style>
Computed
Compute: 계산하다, Computer: 컴퓨터, 계산용 전자 기기, Computed: 계산된
(한번 || 미리) 계산된 정보를 가져다가 쓰는 것
캐싱 되어있는 데이터를 가져온다는 것인데
한번 실행 하고 그 결과를 어딘가에 가지고 있다가 호출 될 때마다 결과만 꺼내주는 거임
<template>
<h1>{{ text }}</h1>
<h1>changeText 함수 호출 값: {{ changeText() }}</h1>
<h1>changeText 함수 호출 값: {{ changeText() }}</h1>
<h1>changeText 함수 호출 값: {{ changeText() }}</h1>
<h2>{{ computedText }}</h2>
<h2>{{ computedText }}</h2>
<h2>{{ computedText }}</h2>
<!-- 함수 모양이지만 데이터 이기에 함수호출 기호쓰면 컴퓨터가 혼냄 -->
<!-- <h2>{{ computedText() }}</h2> -->
</template>
<script>
export default {
data() {
return {
text: "Computed 테스트 데이터 문구입니다.",
};
},
// computed는 캐싱 기능이 있기 때문에 method와 어떤 차이점이 있는지 확인
// 결론 : 캐싱기능이 있어 콘솔로그가 1번만 출력됨
computed: {
computedText() {
console.log("Computed 기능을 생성하였습니다.");
return this.text.split('').reverse().join('')
}
},
// 결론 : 캐싱기능이 없어 콘솔로그가 3번 출력됨
methods: {
changeText() {
console.log('함수 호출');
return this.text.split('').reverse().join('')
},
},
};
</script>
<style lang="scss" scoped></style>
watch
보고 있다는데 뭘 보고 있냐면 data()에 선언한 변수를 보고 있다는 거임
왜 보고 있냐면 변수 값이 변하면 개발자가 정해준데로 해준다는 것
<template>
<button v-on:click="changeMessage">{{ message }}</button>
{{ watchMessage }}
<br />
//<button @click="changeMessage">{{ message }}</button>
</template>
<script>
export default {
data() {
return {
message: "안녕하세요 Vue.js Watch 기능 테스트 오리지널 문구",
watchMessage: "",
};
},
watch: {
// 함수처럼 생긴거지 변수를 바라보고 있는거임
// 변경이 감지되었을 때 동작함
// conputed도 감지 가능
// 보통 게시판에서 한 컬럼을 선택하였을 때, 고유한 id 값이 바뀜을 감지하고
// 이때, 그 id 값에 따른 상세 데이터를 호출할 때, 주로 사용한다.
message() {
// alert('또또 변경됨')
this.watchMessage = "Watch 동작";
},
id() {
// 해당 상세 데이터를 조회하는 api 호출
}
},
methods: {
changeMessage() {
console.log(this.message);
this.message = "변경됨";
},
},
};
</script>
<style lang="scss" scoped></style>
Vue3에서 구현하는 스타일이 2가지가 있음
OptionalAPI, CompositionAPI 팀원과 상의해서 사용하자
OptionalAPI
1. Props(부모가 자식에게)
부모
<template>
<div>
<ChildComponent
v-bind:sendProps1="title"
v-bind:sendProps2="createAt"
:sendProps3="obj"
/>
</div>
</template>
<script>
import ChildComponent from "./components/ChildComponent_OptionalAPIWithProps.vue";
export default {
components: {
ChildComponent,
},
data() {
return {
title: "부모컴포넌트에서 선언된 데이터",
createAt: 2024,
obj: {
id: 2000,
name: "John",
},
};
},
};
</script>
<style lang="scss" scoped></style>
자식
<template>
<div>{{ sendProps1 }}</div>
<div>{{ sendProps2 }}</div>
<div>{{ sendProps3.id }}</div>
<div>{{ sendProps3.name }}</div>
</template>
<script>
export default {
props: {
sendProps1: String,
sendProps2: Number,
sendProps3: Object,
},
data() {
return {};
},
};
</script>
<style lang="scss" scoped></style>
부모에서 data()에 선언한 변수 값을 자식이 받는 형태
<script>에서 <templete> 방향으로 진행됨
2. Emit(자식이 부모에게)
자식
<template>
<button @click="sendEvent">자식컴포넌트에서 만든 버튼</button>
</template>
<script>
export default {
data() {
return {
text: "자식 컴포넌트에서 선언된 데이터",
};
},
methods: {
sendEvent() {
this.$emit("send-event", this.text);
},
},
};
</script>
<style lang="scss" scoped></style>
부모
<template>
<div>
부모컴포넌트 레이아웃
<ChildComponent @send-event="parentEvent" />
</div>
</template>
<script>
import ChildComponent from "./components/ChildComponent_OptionalAPIWithEmit.vue";
export default {
components: {
ChildComponent,
},
methods: {
parentEvent(event) {
console.log(event);
},
},
};
</script>
<style lang="scss" scoped></style>
$emit을 사용한 것이 특징
Spring 에서 requset.setAttribute("send-event", text); 사용하는 느낌적인 느낌
부모쪽에서 자식이 만들어준 이벤트를 실행 하면 자식이 넘겨준 결과 값으로 부모가 조절하는 느낌
된장찌개 끓이다가 '두부가져와라' 하면 자식이 두부 한 모 부모님한테 주고 부모님은 두부 자르는 느낌
CompositionAPI
내장객체를 활용하며 TypeScript(setup lang="ts")와 같이 동작해 봄
import를 잘보자
- ref: 단일 변수 초기값 지정
- reactive: 객체의 속성 값 지정
Props
부모
<template>
<div>
<ChildComponent
v-bind:sendProps1="title"
v-bind:sendProps2="createAt"
:sendProps3="obj"
/>
</div>
</template>
<script setup lang="ts">
import { ref, reactive } from "vue";
import ChildComponent from "./components/ChildComponent_CompositionAPIWithProps.vue";
interface Obj {
id: number;
name: string;
}
const title = ref<string>("부모컴포넌트에서 선언된 데이터");
const createAt = ref<number>(2024);
const obj = reactive<Obj>({
id: 2000,
name: "John",
});
</script>
<style lang="scss" scoped></style>
자식
<template>
<div>toRefs 미사용</div>
<div>{{ props.sendProps1 }}</div>
<div>{{ props.sendProps2 }}</div>
<div>{{ props.sendProps3.id }}</div>
<div>{{ props.sendProps3.name }}</div>
<br />
<div>toRefs 사용</div>
<div>{{ sendProps1 }}</div>
<div>{{ sendProps2 }}</div>
<div>{{ sendProps3.id }}</div>
<div>{{ sendProps3.name }}</div>
</template>
<script setup lang="ts">
// import { defineProps } from 'vue' // 안해도 됨
import { toRefs } from "vue";
interface Obj {
id: number;
name: string;
}
// 1. 컴포지션 API에서 타입스크립트를 활용하는 방법
// 1-1. Prop 받은 데이터 형식에 맞게 타입을 지정해준다.
// Prop 받은 데이터 이름 자체에 미리 선언해둔 타입을 설정해준다.
interface Props {
sendProps1: String;
sendProps2: Number;
sendProps3: Obj;
}
// defineProps ToRefs 내장함수를 통해 Prop 받은 데이터를 활용하여 템플릿 부분에 호출하여 사용
const props = defineProps<Props>();
const { sendProps1, sendProps2, sendProps3 } = toRefs(props);
</script>
<style lang="scss" scoped></style>
조금더 체계화 되어 코드스러움이 느껴진다
defineProps()를 사용하는게 특징
Emit
자식
<template>
<button @click="sendEvent">자식컴포넌트에서 만든 버튼</button>
</template>
<script setup lang="ts">
import { ref } from "vue";
const data = ref<string>("자식 컴포넌트에서 선언된 데이터");
const emit = defineEmits(["send-event"]);
const sendEvent = () => {
emit("send-event", data.value);
};
</script>
<style lang="scss" scoped></style>
부모
<template>
<div>
부모컴포넌트 레이아웃
<ChildComponent @send-event="parentEvent" />
</div>
</template>
<script setup lang="ts">
import ChildComponent from "./components/ChildComponent_CompositionAPIWithEmit.vue";
const parentEvent = (event: string) => {
console.log(event);
};
</script>
<style lang="scss" scoped></style>
defineEmit()을 사용한다
v-model, slot, provide, inject 등이 있는데 정리하다 보니 공식문서가 훨씬 정리가 잘 되어 있다
궁금한건 이쪽에서 찾아보는 편이 좋겠다
Vue는 문법적으로 간결하고 구현 방법이 정형화 된 것 처럼 보인다
Django와 비슷한 느낌을 받았고 진입장벽이 낮은 듯했다.
그렇다고 성능이 안좋은 것도 아니다
React 처럼 Virtual DOM 을 활용하여 속도와 리소스 측면에서 이점을 보인다.
영상을 참조하여 작성하였습니다.
'Vue' 카테고리의 다른 글
vue3 + spring legacy + axios 설정(install 생략) (0) | 2024.06.18 |
---|---|
vue-persistedstate (0) | 2024.06.18 |
Cannot read properties of undefined (reading '__vccOpts') (1) | 2024.06.18 |
vue 실행 (1) | 2024.06.18 |
vue 특징 (0) | 2024.06.18 |