일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 빅데이터분석기사필기
- 금융권 부트캠프
- 빅분기
- 데이터분석자격증
- 금융권 it
- 부트캠프
- 전문가특강
- 멀티캠퍼스
- KB국민은행
- kb 취업교육
- 반별이벤트
- autohotkey
- 빅데이터분석기사
- kb취업교육
- 이차원배열
- kb네트워킹캠프
- sql
- SQLD
- 빅분기필기
- kb it's your life
- 첫알고리즘평가
- sql내장함수
- kbit교육
- SQL데이터타입
- kb it's your life 기자단
- 금융권it
- kb it's your life 6기
- kb 기자단
- prefixsum #C언어
- 데이터분석
- Today
- Total
지식보부상님의 공부 일지
Vue [08] 컴포넌트 심화 본문
[1] 단일 파일 컴포넌트에서의 스타일
◈ 전역 CSS
- src/main.js 에서 임포트한 CSS 스타일
- 페이지 전체에 적용됨
- assets/main.css 에 기술
- 다른 컴포넌트들과의 스타일과 충돌 피하는 것 고려해야
◈ 범위 CSS
- 컴포넌트가 렌더링하는 요소에 특성 기반 추가적인 식별자 부여하여 => 충돌 회피
- <style> 태그에 <style scoped> 이용하면 각각의 태그에 대한 스타일 지정이 가능 i.e. 식별자가 부여됨
Child1.vue
<template>
<div class="child">
<h2>Child1</h2>
</div>
</template>
<sciprt>
export default{
name: 'Child1',
};
</sciprt>
<style scoped>
.child {
background-color: yellow;
border: solid 1px black;
margin: 1.5em;
padding: 1em;
}
</style>
Child2.vue
<template>
<div class="child">
<h2>Child2</h2>
</div>
</template>
<sciprt>
export default{
name: 'Child2',
};
</sciprt>
<style scoped>
.child {
background-color: skyblue;
border: solid 1px black;
margin: 1.5em;
padding: 1em;
}
</style>
Child3.vue
<template>
<div class="child">
<h2>Child3</h2>
</div>
</template>
<sciprt>
export default{
name: 'Child3',
};
</sciprt>
<style>
.child {
background-color: pink;
border: solid 1px black;
margin: 1.5em;
padding: 1em;
}
</style>
App.vue
<template>
<div>
<Child1 />
<Child2 />
<Child3 />
</div>
</template>
<script>
import Child1 from './components/Child1.vue';
import Child2 from './components/Child2.vue';
import Child3 from './components/Child3.vue';
export default {
name: 'App',
components: { Child1, Child2, Child3 },
};
</script>
◈ CSS 모듈
- <style module> 이용하여 CSS 스타일을 객체처럼 처리
[2] 슬롯
◈ 슬롯(Slot)
- 부모~자식 컴포넌트 사이에 템플릿 정보를 전달하는 방법
cf) 부모~자식 컴포넌트 사이에 정보 교환 방법: props, 이벤트 (Vue [07] 참고)
- 부모 컴포넌트는 템플릿을 결정, 자식 컴포넌트는 위치를 결정하여 부모→자식으로 템플릿 전달
- 자식 컴포넌트 원하는 위치에 <slot></slot>
- 전달되는 템플릿 없는 경우 보여줄 fallback UI는 <slot>여기!</slot> 사이에 작성
◈ 명명된 슬롯(Named Slot)
- 자식 컴포넌트에 slot 이 여러개 있으면 구분이 필요 => slot name 이용
- 자식 컴포넌트: <slot name="슬롯명"></slot>
- 부모 컴포넌트: <... v-slot: 슬롯명></....> *슬롯 명에 " "(큰따옴표) 없음 주의!
- 화면 레이아웃 관리 목적으로 주로 사용
◈ 범위 슬롯(Scoped Slot)
- 부모 컴포넌트에서 템플릿에 자식 컴포넌트의 데이터를 바인딩할 때 사용
- 전달된 데이터는 슬롯 템플릿 내부범위에서만 사용 가능
src/components/FancyPhotoBox.vue (자식 컴포넌트)
<template lang="">
<div class="card">
<slot name="title"></slot>
<slot name="photo"></slot>
</div>
</template>
<script>
export default {
name: 'FancyPhotoBox',
};
</script>
<style scoped>
.card {
padding: 20px;
background-color: skyblue;
width: 300px;
height: 400px;
border-radius: 10%;
border-color: gray;
border-style: solid;
border-width: 10px;
text-align: center;
}
</style>
src/components/FancyPhotoBox (부모 컴포넌트)
<template lang="">
<div>
<FancyPhotoBox>
<template v-slot:title>
<h1>침교동을 아시나요?</h1>
</template>
<template v-slot:photo>
<img
src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAkGBwgHBgkIBwgKCgkLDRYPDQwMDRsUFRAWIB0iIiAdHx8kKDQsJCYxJx8fLT0tMTU3Ojo6Iys/RD84QzQ5OjcBCgoKDQwNGg8PGjclHyU3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3N//AABEIALIAvQMBIgACEQEDEQH/xAAcAAEAAgMBAQEAAAAAAAAAAAAABgcBBAUDAgj/xABDEAABAwMCAwUFBQYFAgcBAAABAgMEAAURBiESMUEHUWFxgRMUIpGhFSMyQrFSYpLB0fAWMzSi0kOCJSY2U5Ph8Rf/xAAaAQEAAwEBAQAAAAAAAAAAAAAAAQIDBAUG/8QAKREAAwACAQQCAQIHAAAAAAAAAAECAxEEEiExQRNRIjKBBRRCUmFxof/aAAwDAQACEQMRAD8AvGlKUApSlAKUpQClKUApSsK2BoDNK5d/v1r09BMy8y24zHIce5Ue5IG5NRWF2mx7slxWndP3m5ttHCnG20IT6cSs/SgJ9Sq1mdqcm3Em46Lv8dtO6llrIA8+X1rasna9pC6rShcxyC4rkJjfAP4gSn60BYFK8o7zUhpDzK0ONrGUrQrIV4g9a9aAUpSgFKUoBSlKAUpSgFKUoBSlKAUpWDyoDJrl32/WmwRPebvOZit78PtD8Sj3JTzUfKoh2o9ozOkGBDg8D13eTlKCMpZSfzK8e4daomFeLdebnMl65eucp1bX3T0dxJWFDcDB2x07hnl3AWrdO2GbdpZt+hbK5KeOwkSU7efCDsPFR9Kjuq7T2ouQXrpcLstURpBdX7tODSEo4c5wOEHu6n0OTGI3aDNtVtTb9Pw2ILKFe0S6fvHUrz+IK254GRgiuXftZXy+suxp01fujrgdMZv4WwoDmE9N8kjlk5xQHLnXKdcPZpnTZMpLWfZh91S+Dvxk7elXj2TX1uBBRaolzYuJGOFCl+wShavyp41FxXmGwOfPpQNekZ92NIbfjuradbPEhxCilST3gigP1/e9U2nT7bQvc5iI88klCHFE8WMZ3xnqOlflLU1wYut+nTosREVh94rQw3gBIzy22+VeV3vd0vRbXdp8iYppPChT6yspHma5w8qAm/ZlrafpW8sMtrLtukrCHo61HhGTjjT3EfXlV4an7SrdpWbHjXllSy+jjHuigtaU9FFJxgHoQTyr836Zl26DdEyLsmcqMgEhEJ0NrUegKug8t6l3anr+HrAQkW6ItptlshZkoT7TORyIJ8efj30B+h9O6htWpIQmWaWiSznBxkKQe5STuDXWr8a6a1HdNMzxMs0pbLm3GD+Bwdyk8iK/THZ1r2FrSEeAe73BhI94jE5/7knmUn5j6kCZUpSgFKUoBSlKAUpSgFKUoBWDy3rNeMxfs4jzh/K2o/SgPx7rK4ruuqrtOcVxF6W4R4JBwkfID5VyWGXX3UtMNqccVslKBkmsoS5IeShCFLcWrASkZJJ6Crx0bpqPp62o4whU1xPE+6By/cHgPr8sWiOpmHIzzhnbK1g9n2oJYClx0Rgd/v3Ak48hk1I4PZWgbz7kTn8rCP5n+lSTUOr41rS4mOPbvJzxqJIQjG3PrvgbdfI1F4PadISvE6AhxvOSpglKkjyJIP0rTpleTiWTlZFuVpHXa7MbGkYW9MWe/jSP5V7I7ONOp2KJKz4u11rLqqz3ogRJQS8R/kuDgX8uR9K7ODzIyDyNaKYZx3n5EvVNoiyez7TY2MR0+BfX/Wiuz7TRSQIS0+IfVn9alClpbSVrUEpSMkk4AFQfUvaHEhcTNlCZb3JTpz7JPl+1+njUNRPcnHfJyvs2ZkdmFmdyWJMtk9BxAj9KjN67N7nCSXLetM1sDPAkcLg9DsfQmt2Br7Uckkt2tmWgcw0w4fqDXeg9oEV32abhAejqUrhVwqCuBWcYIOD1T/FVNQzr6uXj89yoHWnGVqbdQpC0nCkqTgiutpC+Pac1FCubC1JLLqfaAH8bZ/Ek+YzVt6h01btUwkv4SiQtALUkDCsY2Ch1FUnPiuwZkiK+MOMuKbXjlxA4/lWdTo7MHIWVdvJ+1kkHBB5javqteF/pGM8/Zpz8q2KqdApSlAKUpQClKUApSlAK0L4rgss9XdGcP+01uOKCEKUo4AGSe6q9vnadpN2NcbezdEuPe6upS4ltXslK4TgBXI56Y28aEMpPstholapS44kKRGaU6Af2tgD6cWat2fCbnxiw8twNFQUoNLKSv90+dVz2NozLubmPjDSEg+Z/niu/fJ0+931Wn7O8qOy0ninSkHcZ/KD647/lW8aUnk8tVkz+dJHrc5Wk7VxRJDDMl9RHEwhr2zhIHXn9T3nvrhSW7NKTxDQ1xDfRaEFs+eBU4tFkttmZDUCMlKurqhlxXma6Hz9Kt0bMFyJl9t/72VVbrBYZ9wb+ybhIhzG1ZTDnt/HxY2wRzwd8b1YljhzoMER5z6ZCkbNqHxHHiTuem/n6ed/sEK+McElvheA+B9I+Ns9N+7wrR0ZcpclmXbbmrin2132bis5K074V9P076StMtlyfNj2n4PS+2SZeZQZcmJbtyQPukA8StgCD37FWO7ao97XR+lnfdo8ZdxnjnwoDqweu52HpXa1hPlOOxrFaFlE2cPjdG/sWRzV4dflXSsVhg2KMGIjQLmPjeV+JZ8T/ACo1t9iJydONOvHpeCP/AONpoSAxpW4hHfwqG3omvSFrWxXR5MW5xfdXgccMtAKQfPp8hUwrmXywW6+seynMJK8YS6jZaPEGp6aXfZVZcDfdaOkMcIwQU4zkcsdMVS2sIfH2hvRf/fktf7wk/wA6lenps3S9+b05dHVPQ3v9G+Tyz+H0PLHQ1F9fyFR9fSJDZ4XGlMrHgQhJrO2qR18PG8eZ+00frBAxX1VKM9tk1qchy46eU1aHFYS8OLjCf2txg+W1XDb5sa4xGJkN5D0d5HG24kjChWOtHp72bVKUoSKUpQClKUApShoCr+3a+yYFgi2a3qWmTdnS0eEYJbGOIA+JUkeRNQCdpe3WvSkzDCHJKI6lKkqGVcWPynoOlTHthQtetdIB0AsgvqTn9oFJ/wCNQ/VN2uTCLhBetKlQ3GylElAUcJI5npXXgmFjqqODk1keWIh69s8ex5lQVdXeacNDPf8Aire0s/fRJvZsunXLiTcXfbvpkJRg52Tgjpz59a1OyFSfZ3FIzx/AVDbl4de/wqb9mc5Fo1zqGxSFBHv6xOiA/nznjA+fL901g9qVoKYvPc1/g0kr12s4Tok4/emtj+dfM6VrO2wX507R6WY0dtTjrhuTXwpAyTgbmrnBzuK8Z0RifDfhzGkvR30FtxtXJSSMEVHyV9mz4eD+0oGya3u+oJ4g2XT6JEopKg2ZQGw5nJAG2R1r20z9oJ13fE3aCIMpUZBcjhYXg/Djcd4/WrD0j2d2bRE+Zd2pT7qi0pKVSCMMN8zuOZ2593rUK0nJVfLzf9SlBbbuEkJj8Q3LaBj9MfKrS3TMORixYsNdK0aftLw9ry7Gx2Y3N1iMy2sB9LfAkgK5q8T9Kag1he9NuNIvmmTFXIBUjM1KuIDn+EHvrqfan+ENcs3x9B+ybgwmHMcRyaVn4VnwwAP4qnOtdDWnXLMJcuQ+2uPlbL8Zad0qxnmCCDgHNRVVLa2WxYMOXHNNb7FfWPUd7vUETrdpOZIjqUU+0YkJIyOY3ArpCTqZQ/8ARly/7nm6sfSun4emLMxarfxlhrJ41qypSickmuurZJqPkov/ACWD6Pzb2kvXZ6NCcmabnW5bMgBuQ9ukkj8II2zkZ9KjPaGVf4xnqXz+7B/+NNW92sz2rzqaxaXYPtCy+Jswjf2aQDgeeOL5jvqqNaN+962kspXlTzyG8hHDgnAx4+fWndrZeJib6V9MstcRp22phSEBbXswhSSOgGK7PYU8tqzXWzOrKvs24LQjP7Khn9Qo+tRLT2nV2Z5xS7i/KC0cISrISN+fM8qlXYm2p2Rqm5f9KRcA2gjkeAH/AJiuzl/oltaZx8Fr5bSe0WjWax1rNcB6gpSlAKUpQClKUBWXbiwti0Wi8tJJNuuCVLUPytq2PzISPWonf7xammZFvkzA0+6yQkFKvzDbcDrmrm1HZ49+sk21S9mpTRQVYyUnmFDxBAPpVIIjMQZQs+qYkZFzhgNodkIHDIbT+FaFKG+R058/EDr419nG/Jwc3FL1kab19HF7JXii4yGfuwFt5IKFcW3Ti5AeBqbalsbd3S0+FOMy45y1IZOHG+ux6jwqrtPq911mylpXFwTShKkAnI4iNsVdpyD9DtiqQu2mc3NbjMsk9mzgwu0HWFhSI9ytSL6ynARJjq9m6R+8kA7+g8zW292u3Va+CHoubvzL7pQB5/By9RXQU02v8TbZ86jOqrBOuzaI0NceLEByviWoFQwc5AHLwzVXi0aYue6emad91DqPVgVDvk6Dabcd3IcdwFbo5gKVk7fIeFSKyyrcIzUCDJYX7JofdtOBXCnv2O/n/WoLH0VZmFqTM1JETwg59m4hCuLfnlRqVaT07aLTxybY+JS3BwKeLiVYHPA4dhUwmmU5dzc/q/4dG7O2yY1ItMyVGCnW8LaW6ArB5HHSuHYrzqzRTfu0D2d5tSP8uK8opdbB/ZPd5ZHcBXvq+zWO4lpd0lsw5CBhLinEglPdg88H9TUVRoyGtY+yNVRVjHwILgzsf3VcvSlrZPFvoW9v90WJ/wD2VCGsv6Vu7bmN0hIwPU/0rlXHtN1XesxbBY/sxKx/qpZ4lJB6pyAM/wAVZ0pbJkW2lm7OsyXELPC424pZKegV9ceFd5DTSP8AKbSO8pFQsXsvk57ltJHC01Y0WZuTNmvqfnyAVyJLyvixzO56VWDzj1w1o69ZUNOue9KcjpWocJ4ckdfDP973FenlR7RNeQoJWhhakk9Dg4qqOz+JcjMenwrNMuIaR7LDA/AtXefIfWrNSqSb0iOLd3N35ZMF3a4QNOPzb0yyxLTlLTbSs8ZIwnGCevj0q1+ziyqsGjrdBfBEjgLr4PRajxEemcelRTS2hrnPvDF61c20y3GPFEtra+PhX+2tQ2JH61aA/FTkZfkel6Ori4PiTdeX9GazWKzXOdQpSlAKUpQClKUBg8q5t5slqvbCWbvBjy20nKQ8jJSe8HmK6R5VxNW6kg6Ws7tzuSvu0/C22D8TyzySB/eBvQH5/wC1bTrOmtbKTaowZiOMNyWm0/hRg4Vj1Tn1qzIkhMyHHlNHibebSsHfr3VGGY141fdzf9TIaYjrjrZjwkpOQ2rOAfn5nuFajTGodJEx4bCrpbASpAAytsd2B/8AndW+Pc9zyuY5zPpl90Tffpz6ZqJxGbXKQTqtFzenA8Tsdxp72CME7NhvKSnzyfrXg12gRmiUT7bNjLGxITxY646Vss9oen3DhbzzJzj42T/LNWrpr2Z8Z5cFN9GzemI00phDDUYRWkjJQmzFQV/E0a4E6LY7ekyG1usoO5XEbkxDjxwlSfoK7aNbadUnj+1EJ80L/pWhf9VaduVlmwxc0lTzKkpPsnMZ6b4xzqnQvs7VzsltKsRp2caekrW83E96XkBcmQy9Pc38OHhT9akjSNMQGlly3odLnwqV9kEk+iWwKhPZ7qKz2SzuMzpRQ+6+VqT7JR4RgAbgeHSpOvXunUgqExRx0S0rP6VClP2Xvm5YfTOPaPi6N2CRFdXYLXMj3RIzFciQXY4DnTiJSE8PfnpmpQji4QTjJGNtxUNd7SLTxlMeNLkK6BCAM/XNaT9/1TqBK2bPaXIbWSC87seeD8RAwfDzq89M+Di5Hyclp3KlI9u0jUDTMBVpiKS6+9u/wji4EDff5VPOwa2e5aHTMUpK13CQ48SnoB8AB9UE+tRTTGj49rS5JuS0zpz6SlxSxlAB5jB592fpX1pG6P8AZ5qcWuc5/wCXro4fd1KJIjudM55cwD4YPfVLT8s34mTFLeKfReNZr4QcmvusjvFKUoBSlKAUpSgBrCuVZrBoCN6y1hatIQEybo4pS1khmO0AVukc8DPIbZPIZqrpku5a71XCuF0tUiBaILRUyw+T94snn03zj+GvvUrjEntklt31eEx2GxbUu/gJKUnIzsTkq9fKpQT06jnnnWuOE+55/M5Tx/gl5HLbceHQUwTsNvGmM7YB8DUdtF9ku6iuFkurbaJDZLsdSBgLa5jPjjBz591btpdjypx1e2vRvXW7W+LPiQLijgEpJ9m64gFvbpk9TWoiTpqTc02ptEN6QsE8CUJUnYZ3I26cq6l1tsS7RjGuTCHms54VEjBHUEV5Wux2u0j/AMOhNMqxgrAyojzO9V1RdXj6PL2ebtgsgSpxdphqABJxHTyHd31yIP8AgubE98QzbEt4wpLwSlSPNJ9PpUrrhStHafly1Sn7eguKOTwLUlKj3kA4pS+icWVf1t/sLdbNM3WKmTCgwnmOIjiQwE7jntgV4vs6VtU9iFJgQWHXkktLdjp4SOW6iMV34sZiGwhiK0200j8LaAABWrdrPAvDCGrjHS+hJyjJIKT6GjXYicq6u7ejwtl1sr09yBbXo6pCEcSksI+HA54UNjz766xNaFrs1vtDZbt8RuPn8RAypXmo7mt6pneu5TI5b/HwOW+ceNcrU1mav1legqCQsjiYWfyrH4cefI+ddWsjnvUtJlYpxSpejqdkeoV37SLCZZV79BUYsji5kp5H1Tj1zU2qhJTNy0RcntSWWW45DW8HZ1vVslaSd8d+M+Y76u+1TmLnbok+KSpiSyl1snY8KhkbetclLTPo8WSckqpNylKVBoKUpQClKUArBOBWaUBXvbRpw3vSLz8O3iVcYikraUkfeJRn4wnqduny3qCsa+srVkZUw489JQ2lCYhSrjK8YAzjB8/1NX2eVcs6esvv4uH2TA99ByJHuyC4D38WM1aacvZjmwRlSVeilHu0BlhsMPWa5N3Ej4Yq0AZPcCcH/b6VsaXs9zeurmodQFKJjiChqOn/AKSfH02A+ddrtZR7PX+jpCuSy438lJ/5V08nkOWa1j8u553K6cH4wvPsyM5251x9SXGfaYbUqDB97aS5iQ2AeJKMc048fOuvStWt+zzsdKa7rZE4uuoU+THi2y3z5LziwHE8IAaHjjOf736VLMjlse7FKyMdTjxpKr2Xy3D/AETo4Fz1TEtF59xuiFR2ltpU1KUCUKPUctv7zjYn0t2qrRcrl9nwZKn3ikq40tqCTjx/seNdOZCiTmvZzozEhAOQl5sKAPeM8qRIMSCgohxWGEnoygIH0qv5bLOsLnw9mweXPHjUa7QLhJt+nFuQlKbW46lpTqTgtpOcn+XrUkrUusBm6W6RBk/5byME93UH54qa21opipTadLsLRD+z7ZHiB918NJx7V05Uvrz9f07q2yQkEqOAAST3VAX9OavRCchC/t+4obwnYhxQHJOQnP1r70VprWOrrA06i/tM2t1SmnC4Ct5IBwQPhycj96s3fStHauJ81Opo+9QakY1HGTY9MqdmTprgbIQ0r4EZ3O4+vTnV46dtqbPY4FsQsuCIwhnjIxxcIxnFamldM2vTFvah2uMhGE4ceKR7R0/tKI5/oK7tY1To9TFinFPTIpSlQailKUApSlAKUpQA18mvquJrS8r0/pa5XVpsOOxmeJtKuXESAM+GSM0BXvb3IjR49klNyWftCHNDiGSscZRjJOO4FKfnW+y4l9hp9v8AA4kKT5EZFRHSem40uK3fb4n3+5Tvv1OPnISFbjbln9OnKpiMAYSRgDGBXRin2eLz80W9L0KUpWp54pT6VA+0SXqK2LE63T/Y29XCgoawFJWc7nI/n6VWq0a4cXy3070TylcjSZmL0/DeuMj3h95sO8fDjAUAQnzGeddepT2VuemnIpSlSUNK9vmLZp8gc2ozix6JJru9ikcMdnNrV+Z0vLV6uKH6AVzH2W5DDjD4CmnEFCweqSMEVo9lMuTYtVT9IOPLegFn3uEVKyWskcSfXOfME/mNYZV7PW/htrvPstus1is1ieoKUpQClKUApSlAKUpQCtK8W6NdrZKt01BXHktKbcAODg9x6Gt2lAUwjQOubQDBsl4tr0BOzC5SSHEJPTHCf1PpXHtd3nafv9ys2tbhwvI4FMOqThtQwclJwNuXyNX9XLu9gtN8CE3e3Rpgb/D7ZsKKfI1KpoxvjxaaaKsmax09EZUtVzZcA/IweNSvLFatp1vaZxeTJV9muNEYRKUE8STyP/1Vnw9EaXhOpeiWG3tuIOUq9iFEH15V9XrR2nr9ID93tUeS8lISHDlKuEchkEbVp8rOZfw/DrXcrqVq7T8VHGu6xlY3w0rjJ/hriKtl47TloZtsdVvsrJK/fJKT98sA4wBz9OXf0q1YfZzo+G6l1mwww4k5SV8TmPRRqUJQlCQlCUpSkYAAwAKrVtmmHh48L6l3KEtepjYOGw6tYct8yGkNJXwkodSNgcjPQcxt+le0rXTbr/BYbfKu6Wk8chTDa8Np7/w/XYVdk+2wrg2lu4Q48lA5JeaCwPLNZhW6HAb9lBjMRkfsstBAPyoslIPh4nXVop6DrbT8uP7Uz0xzjKkPfCpPh1z6VzhqW+3qYo6NtLtwgxQfbrU3gOE9Bvt5c9+VW9cNG6auEoyp1kgPPk/EtTIyrz7668OIxDZSxEZbYZQMJbbQEpT6CjyUI4WGXspQ3XWcn7iDomW1IO3E/ngHzCf1qY9nOibhZ7nJ1BqOU3Iu0tr2Xs2h8LCMg4B5Hkkbcsdc1YVKh035NowxH6VoVmlKqailKUApSlAKUpQClKUApSlAKUpQClKUApSlAKUpQClKUApSlAKUpQClKUApSlAf/9k="
alt="침교동"
width="300px"
/>
</template>
</FancyPhotoBox>
</div>
</template>
<script>
import FancyPhotoBox from './FancyPhotoBox.vue';
export default {
name: 'FancyPhotoBoxParent',
components: { FancyPhotoBox },
};
</script>
<style lang=""></style>
src/App.vue
<script setup>
import FancyPhotoBoxParent from './components/FancyPhotoBoxParent.vue';
</script>
<template>
<FancyPhotoBoxParent />
</template>
[3] 동적 컴포넌트
◈ 동적 컴포넌트(Dynamic Component)
- 화면 동일한 위치에 여러 컴포넌트 표현해야 하는 경우 用 (v-if 적용하는 것과 동일 효과)
- <component> 요소 템플릿에 작성
[4] 컴포넌트에서의 v-model 디렉티브
◈ 사용자 정의 v-model 만들기
- 부모 컴포넌트: <child-component v-model:message="parentMessage" />
- 자식 컴포넌트: update:사용자정의 모델명
[5] provide, inject를 이용한 공용 데이터 사용
◈ provide, inject
- 기존 props는 계층 구조 따라 연속적으로 속성 전달해야한다는 문제점이 있었음
=> 공용 데이터를 부모 컴포넌트(App)에서 provide 하고, 하위 컴포넌트 어디든 데이터 inject 하면 用 가능하도록 함
- 공통 조상끼리만 사용 가능하다는 단점도 있음
[6] 텔레포트
◈ 텔레포트(Teleport)
- 컴포넌트 트리 계층구조와 관계없이 별도의 요소에 렌더링해야하는 경우 用
- 애플리케이션에서 모달, 튤립과 같이 메이니 화면에 독립적이게 공유 UI 제공하는 경우 用
src/components/Modal.vue (자식 컴포넌트)
<template lang="">
<div class="modal-overlay" v-if="visible">
<div class="modal">
<button class="close" @click="sendClose">닫기</button>
<div class="modal-content">
<slot></slot>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'Modal',
props: {
visible: {
type: Boolean,
required: true,
},
},
methods: {
sendClose() {
this.$emit('close');
},
},
};
</script>
<style scoped>
.modal-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
}
.modal {
background: white;
padding: 20px;
border-radius: 5px;
position: relative;
}
.close-button {
position: absolute;
top: 10px;
right: 10px;
background: transparent;
border: none;
font-size: 20px;
font-weight: 700;
cursor: pointer;
}
.modal-content {
margin-top: 40px;
}
</style>
src/components/ModalParent.vue (부모 컴포넌트)
<template lang="">
<div>
<button @click="showModal">모달 열기</button>
<Modal :visible="isModalVisible" @close="hideModal">
<h2>모달 내용</h2>
<p>안녕하세요</p>
</Modal>
</div>
</template>
<script>
import Modal from './Modal.vue';
export default {
name: 'ModalParent',
components: { Modal },
data() {
return {
isModalVisible: false,
};
},
methods: {
showModal() {
this.isModalVisible = true;
},
hideModal() {
this.isModalVisible = false;
},
},
};
</script>
<style lang=""></style>
src/App.vue
<script setup>
import ModalParent from './components/ModalParent.vue';
</script>
<template>
<ModalParent />
</template>
'KB IT's Your Life > Vue' 카테고리의 다른 글
Vue[10-1] vue-router를 이용한 라우팅 (1) | 2025.03.28 |
---|---|
Vue [09] Composition API (0) | 2025.03.27 |
Vue [07-2] TodoList 예제 리팩토링 (0) | 2025.03.27 |
Vue [07-1] 단일 파일 컴포넌트를 이용한 Vue 애플리케이션 개발 (1) | 2025.03.27 |
Vue [05] 이벤트 처리 (1) | 2025.03.26 |