일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 웹해킹
- node.js
- materialize
- gitbash
- 포렌식
- NavBar
- 워게임추천
- 자바문제풀이
- 워게임
- CTF
- 자바
- 웹해킹기초
- nodeJS
- 써니나타스
- MongoDB
- GIT
- 포렌식워게임
- 자료구조
- Express
- 웹기초
- 웹개발
- node
- 자바기초
- 그래프
- 뷰
- bootstrap
- 이진탐색트리
- 이진트리
- mongoose
- wargame.kr
- Today
- Total
보안 전공생의 공부
슬롯(slot) 본문
◆ 슬롯 : 부모 컴포넌트에서 자녀 컴포넌트에 나타나야 할 콘텐츠 제공 가능
부모 컴포넌트가 자녀 컴포넌트로부터 데이터 전달 받기 가능
(컴포넌트 재사용 ↑)
1) unnamed slot (default slot)
- 가장 기본적인 슬롯
- 부모 컴포넌트의 일부 -> 자녀 컴포넌트 inject 가능
부모 컴포넌트의 DOM(Document Object Model) 엘리먼트들 ( e.g. p, div, img )
-> 자녀 컴포넌트에 정의된 <slot></slot> 태그 위치에 대체 가능함
<slot></slot> 태그 無 -> 부모 컴포넌트에서 html 엘리먼트를 전달해도 자녀 컴포넌트에 표시 X
cmd 창에 vue create unnameslotwithcli --default 입력 -> 프로젝트 생성
해당 폴더 vscode로 실행
App.vue를 위처럼 수정 !
Child 컴포넌트에 주입할 내용을 포함하였다.
components 폴더에 Child.vue를 추가하고 위처럼 코드 작성하였다.
npm run serve 명령을 통해 실행 결과를 확인해보면
위와 같다.
자녀 컴포넌트 코드 내의 slot 태그 덕분에
부모 컴포넌트에서 전달한 <p>두찜 로제찜닭 먹구시포ㅠ</p>가 나타난다.
2) named slot
- unnamed slot에 name 속성(attribute)가 포함된 형태
- 원하는 위치에 다양한 유형의 다수 콘텐츠를 삽입해야할 경우 사용함
(하나의 슬롯만 이용한다면 unnamed slot 이용해도 됨)
<slot name="slot_name"></slot>
cmd창에 vue create namedslot --default를 입력 -> 프로젝트 생성
생성된 프로젝트>assets>imgs 디렉터리 생성 -> imgs 내에 jpg 파일들 저장하기
(Vienna.jpg, paris.jpg, dresden.jpg, amsterdam.jpg )
[ChildComp.vue]
<template>
<div class="main">
<div class="best">
<h3>추천하는 관광지</h3>
<slot name="best"></slot>
</div>
<div class="city">
<h3>{{ran_city.cityname}}</h3>
<img src="ran_city.pic"/>
</div>
<div class="footer">
<slot name="footer"></slot>
</div>
</div>
</template>
<script>
export default {
props : ['ran_city']
}
</script>
<style>
.main{border : 4px Solid blue;}
.best {border : 4px solid teal; margin : 4px;}
.city {border : 4px solid lime; margin : 4px;}
figcaption, h3{font-family : sans-serif; text-align: center; padding: 2px 0;
width: 100%;}
img{display : block; margin-left: auto; margin-right: auto; width: 60%;}
.footer{bottom : 0px; color:white; background-color:teal; width: 100%;
text-align: center;}
</style>
best, footer라는 이름의 named slot 사용 ! -> 이 부분에 부모 컴포넌트인 App.vue에서 정의되는 내용을 주입함
class City : div 내에 이미지를 배치하는데 props를 이용해 부모 컴포넌트인 App.vue에서 이에 대한 데이터 전달받도록 함
[App.vue]
<template>
<div id="app">
<child-comp :ran_city="randomCity">
<div slot="best">
<figure>
<img src="@/assets/imgs/Vienna.jpg"/>
<figcaption>비엔나(Vienna)</figcaption>
</figure>
</div>
<div slot="footer">
<footer>
<p>© All right reserved</p>
</footer>
</div>
</child-comp>
</div>
</template>
<script>
import ChildComp from './components/ChildComp.vue'
export default {
name: 'app',
components: {
'child-comp':ChildComp
},
data(){
return{
cities:[
{cityname:'paris', pic: '@/assets/imgs/paris.jpg'},
{cityname:'amsterdam', pic: '@/assets/imgs/amsterdam.jpg'},
{cityname:'dresden', pic: '@/assets/imgs/dresden.jpg'}
]
}
},
computed:{
randomCity(){
return this.cities[Math.floor(Math.random()*this.cities.length)]
}
}
}
</script>
자녀 컴포넌트 ChildComp에 넘겨줄 이미지 정보 -> randomCity()에서 cities 에 정이된 이미지 정보를 랜덤하게 선택해서 전달하게 한다.
두번째 칸은 새로고침할 때마다 city가 무작위로 선택되어 전달되는 것을 확인할 수 있다 !
(이미지 파일은 jfif를 jpg로 고쳐서 출력이 안됨 ㅠㅠ)
3) sxopped slot
- Vue.js 2.1 버전 이후에 추가된 기능
- 기존 슬롯이 이미 렌더링된 html 태그(e.g. p, div)를 전달했던 것과 달리
템플릿을 이용하는 재사용 가능한 특별한 슬롯
- 필요한 경우 자녀 컴포넌트 -> 부모 컴포넌트 데이터 전달 가능
cmd창에 vue create scopedslotwithcli --default 입력 -> 프로젝트 생성
[App.vue]
<template>
<div id="app">
<travel-list>
<template slot-scope="{ childitems }">
<p v-for="item in childitems" :key="item">{{item}}</p>
</template>
</travel-list>
</div>
</template>
<script>
import TravelList from './components/TravelList.vue'
export default {
name: 'app',
components: { TravelList },
data(){
//return { cities: ['Paris','Budapest','Seattle','Vancouver','Prague']}
}
}
</script>
template 시작 태그 안에서 slot-scope로 자녀 컴포넌트인 TravelListvue로부터 전달받을 데이터로 childitems를 정의하고,
받은 데이터를 v-for 디렉티브를 이용해 나타낸다.
[TravelList.vue]
<template>
<div>
<p><input v-model="inputFilter"/></p>
<slot :childitems = "childitems"/>
</div>
</template>
<script>
export default {
//props:["items"],
data(){
return{
inputFilter:"",
childitems:['one','two','three']
}
},
//computed: {
// filteredList(){
// return this.items.filter(item=>item.includes(this.inputFilter))
// }
// }
}
</script>
slot 태그 안에서 부모 컴포넌트에 전달한 데이터인 childitems를 정의하고,
그 데이터들은 data 객체 내에서 정의했다.
자녀 컴포넌트인 TravelList.vue로부터 전달받을 데이터 -> 부모 컴포넌트인 App.vue에 표시됨
=> $emit()메서드를 사용하지 않고도 자녀 컴포넌트 -> 부모 컴포넌트로의 데이터 전달 가능 !!
위의 App.vue와 TravelList.vue의 코드를 수정하여
부모 컴포넌트에서 데이터를 전달하면 전달된 데이터를 이용해 동적으로 필터링해서
그 데이터를 나타내는 형태로 바꿔보았다.
[App.vue]
<template>
<div id="app">
<travel-list :items="cities">
<template slot-scope="{ items }">
<p v-for="item in items" :key="item">{{item}}</p>
</template>
</travel-list>
</div>
</template>
<script>
import TravelList from './components/TravelList.vue'
export default {
name: 'app',
components: { TravelList },
data(){
return { cities: ['Paris','Budapest','Seattle','Vancouver','Prague']}
}
}
</script>
[TravelList.vue]
<template>
<div>
<p><input v-model="inputFilter"/></p>
<slot :items = "filteredList"/>
</div>
</template>
<script>
export default {
props:["items"],
data(){
return{
inputFilter:"",
// childitems:['one','two','three']
}
},
computed: {
filteredList(){
return this.items.filter(item=>item.includes(this.inputFilter))
}
}
}
</script>
실행화면은 밑과 같다.
'WEB > Vue' 카테고리의 다른 글
Materialize(1) - Button, Table, Card, Navbar (0) | 2021.05.17 |
---|---|
Materialize 설치, 사용 방법 (0) | 2021.05.03 |
이벤트 버스 - 관계 없는 컴포넌트 간 통신 (0) | 2021.02.27 |
컴포넌트 정의 및 등록 / 컴포넌트 간의 통신 (0) | 2021.01.27 |
디렉터리 | 이벤트 처리 : v-on (0) | 2021.01.27 |