일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 고양이 사진 검색기
- nextjs사용법
- 프로그래머스 K_Digital Training
- Vue
- 쌓임맥락
- 프로그래머스 프론트엔드 데브코스
- 프로그래머스 데브코스 프론트엔드
- SCSS use
- 리스트 렌더링
- react next
- SCSS extend
- 이벤트 수식어
- vue 지역 컴포넌트
- SCSS import
- 폼 입력 바인딩
- intersection opserver
- git 같은계정 다른 컴퓨터
- flex
- postcss
- 다른컴퓨터에서 git사용
- vue 이벤트 수신
- vue mixin
- Spacer
- KDT 프로그래머스 데브코스 프론트엔드
- vuex map
- SCSS forward
- 프로그래머스 데브코스
- netlify redirect
- 리액트
- KDT 프로그래머스
- Today
- Total
혼자 적어보는 노트
프로그래머스 데브코스 TIL - Day 38 본문
✅ 오늘의 학습
📌 Vue (5)
- 컴포넌트 등록
- Props
- Non-Props
- 커스텀 이벤트
- Slots
- 동적 컴포넌트
- Refs
전역 컴포넌트
- main.js에서 생성한 app에 component 메서드를 통해 등록한 컴포넌트.
- 전역으로 컴포넌트를 등록하면 컴포넌트 어디에서든지 import를 하지 않고 등록한 컴포넌트를 사용할 수 있다.
import { createApp } from 'vue';
import App from '~/App';
import Btn from '~/components/Btn';
const app = createApp(App);
app.component('Btn', Btn);
app.mount('#app');
지역 컴포넌트
- 컴포넌트 내부에서 components 옵션을 통해 등록한 컴포넌트.
- 해당 컴포넌트 내부에서만 사용할 수 있다.
<template>
<h1>Hello vue</h1>
<Btn /> // 전역 컴포넌트
<Hello /> // 지역 컴포넌트
</template>
<script>
import Hello from '~/components/Hello';
export default {
components: {
Hello
}
};
</script>
컴포넌트 내부에서 props 데이터 수정하기
컴포넌트 내부에서는 props로 받은 데이터를 직접 수정할 수 없기 때문에
props로 받은 데이터를 컴포넌트 내부에서 데이터를 따로 담아서
해당 데이터를 변경하는 방식으로 사용할 수 있다.
<template>
<h1 @click="updateMessage">
{{ newMessage }}
</h1>
</template>
<script>
export default{
props: ['message'],
data(){
return {
newMessage: this.message // props로 받은 데이터 할당
};
},
methods:{
updateMessage(){
this.newMessage = 'New Message!';
}
}
};
</script>
props
props로 전달할 데이터가 객체라면 객체 내부의 프로퍼티들을 한번에 전달할 수 있다.
<template>
<Hello v-bind="post" />
</template>
참조형 데이터 타입 체크
객체나 배열의 default값은 항상 함수로부터 반환이 되어야한다.
props:{
id: Number,
title: [String, Number],
email:{
type: String,
default: '1111@abc.com'
}
data:{
type: Object,
// 객체나 배열의 기본 값은 함수로 반환
default: function() {
return { message: 'hello' }
}
},
},
Props 대소문자 구분
HTML 속성명은 대소문자를 구분하지 않기 때문에
props를 통해 전달할 데이터 이름은 html상에서 케밥케이스로 작성을 하고
props를 받는 컴포넌트 내부에서는 카멜케이스를 사용해야 한다.
// HTML
<Post post-title="hello~" />
// Component Props
props: [postTitle]
non-prop 속성 ($attrs)
props나 emits에 정의 된 특성을 가지지 않은 속성 또는 이벤트리스너를 의미한다.
(ex: class, style, id, 이벤트 리스너)
상위 컴포넌트에서 하위 컴포넌트에 속성을 전달해 줄 때
하위 컴포넌트 내부에 최상위 요소가 하나일 경우 상속이 되고,
여러 개일 경우 $attrs를 사용하여 전달된 속성을 나누어 줄 수 있다.
❗❗ props로 명시를 한 속성들은 $attrs의 내장객체로 들어가지 않는다.
[App.vue]
<template>
<h1>
{{ msg }}
</h1>
<Hello
class="hello"
style="font-size:100px"
@click="msg += '!!'" />
</template>
[Hello.vue]
<template>
<h1 :class="$attrs.class">
Hello
</h1>
<h2 :style="$attrs.style">
Hello
</h2>
<h3 @click="$attrs.onClick">
Hello
</h3>
</template>
❗❗ 이벤트리스너를 전달받아서 사용할 때는 on키워드와 함께 사용해야 한다.
💡 모든 속성을 한 요소에 전달하기
<template>
<h1 v-bind="$attrs">
Hello
</h1>
<h2>Hello</h2>
<h3>Hello</h3>
</template>
💡상속을 원하지 않는 경우엔 하위 컴포넌트에서 inheritAttrs옵션을 추가한다.
inheritAttrs: false,
하위 컴포넌트에 이벤트 리스너 전달
<Hello @click="msg += '!'" />
커스텀 이벤트가 아닌 네이티브 이벤트 리스너를 전달할 경우
emits옵션에 명시를 하면 내부 요소에 지정해서 이벤트 리스너를 추가할 수 있다.
<template>
<div>
<h1>A</h1>
<h1 @click="$emit('click')">
B
</h1>
</div>
</template>
<script>
export default {
emits:['click'],
};
</script>
컴포넌트의 양방향 데이터 바인딩
[App.vue]
<template>
<h1>
{{ msg }}
</h1>
<Hello v-model:message="msg" />
</template>
v-model에 데이터명을 붙이지 않으면 modelValue로 전달이 된다.
[Hello.vue]
<template>
<label>
<input
:value="message"
@input="$emit('update:message', $event.target.value)" />
</label>
</template>
<script>
export default {
props:{
message:{
type: String,
default: ''
}
},
emits:['update:message'],
};
</script>
양방향 데이터 바인딩을 할 경우 $emit의 이벤트 이름은
update:[변경할 props이름]으로 지정해야 한다.
slot
컴포넌트 사이에 내용을 입력하면 내부의 컴포넌트의 slot태그 위치에 작성된다.
컴포넌트 사이에 내용이 없다면 slot태그 사이에 작성한 내용이 출력된다
컴포넌트의 내용을 분리해서 출력하고 싶다면 template에 name을 지정하여 아래와 같이 작성할 수 있다.
* #은 v-slot:의 약어
<template>
<Hello>
<template #star>
<h2>★</h2>
</template>
<template #heart>
<h2>♥</h2>
</template>
</Hello>
</template>
<template>
<slot name="star">
X
</slot>
<h2>---------</h2>
<slot name="heart">
X
</slot>
</template>
범위를 가지는 Slot
슬롯에서 사용한 데이터를 슬롯을 사용한 범위에서 사용할 수 있다.
<template>
<Hello>
<template #default="slotProps">
<h2>Hello {{ slotProps.num }}</h2>
</template>
</Hello>
</template>
<template>
<slot :num="123"></slot>
</template>
동적 컴포넌트
<component :is="currentComponent" />
currentComponent의 값을 변경해가면서 컴포넌트의 노출을 변경할 수 있다.
keep-alive
토글 기능으로 currentComponent 의 값을 계속 바꿔주면 바꿀 때마다 컴포넌트가 생성되고 사라지는데
keep-alive로 래핑하면 한번 렌더링한 컴포넌트를 캐싱하여 다시 렌더링을 시키지 않는다.
* 캐싱을 하면 메모리를 소모하기 때문에 토글이 자주 일어나는 곳에서만 사용하는 것이 좋다.
<keep-alive>
<component :is="currentComponent" />
</keep-alive>
Refs
ref 속성을 이용해 DOM에 직접 접근할 수있다.
* 해당 dom을 변경하려면 mounted 되었을 때 접근해야 한다.
<input ref="usernameInput" />
methods: {
focusInput() {
this.$refs.input.focus()
}
},
$nextTick
반응형 데이터는 변경되자마자 바로 적용이 되는 것 처럼 보이지만
vue내부의 최적화 과정으로 인해 완전 즉시 적용이 되는 것은 아니다.
setTimeout의 콜백함수를 통해 약간의 시간을 지연시킨 후에 적용시키는 방법도 있지만
vue의 내장 메서드인 $nextTick을 사용하면 같은 방식으로 구현할 수 있다.
✍ 느낀 점
지난 주 과제 때문에 강의가 조금 밀려있기도 했고 강의 내용이 많은 걸 다루다보니
이번 주는 거의 종일 강의만 들었다..
오늘은 거진 10시간을 강의듣고 정리만 하니깐 정신적으로 피곤한 느낌이다😱
그래도 이것 저것 공식문서에 있는것을 차례대로 짚어주며 하나씩 해보니
시간은 걸리지만 그래도 머릿속에 기억이 되는 것 같다.
물론 실제로 사용할 때도 딱딱 떠오를지는 아직 확신이 없지만..
잊어버리기 전에 빨리 과제를 진행해서 직접 부딪혀봐야겠다!
'스터디' 카테고리의 다른 글
프로그래머스 데브코스 TIL - Day 40 (0) | 2022.05.14 |
---|---|
프로그래머스 데브코스 TIL - Day 39 (0) | 2022.05.13 |
프로그래머스 데브코스 TIL - Day 37 (0) | 2022.05.11 |
프로그래머스 데브코스 TIL - Day 36 (0) | 2022.05.11 |
프로그래머스 데브코스 - 노션 과제 피드백 (0) | 2022.05.10 |