오늘은 필터 선택 기능을 만들거임
필터 박스를 클릭 시 app.vue에 클릭한 필터명을 전달해보자
즉, 상위 컴포넌트에 전달하는거다
상위 컴포넌트에 전달할때는 단순히 custom event를 사용하면 되지만
상위 상위에 전달할때는 아직 우리가 모름ㅋ
그게 바로 mitt 입니다.

mitt는 라이브러리여서 터미널 켜서 다운 받으셈ㅋ
❯ yarn add mitt
이렇게 설치한 다음 main.js에서 라이브러리를 등록하고 변수 설정을 해주자
import { createApp } from 'vue'
import App from './App.vue'
import mitt from 'mitt'
let emitter = mitt();
let app = createApp(App)
app.config.globalProperties.emitter = emitter; //글로벌한 변수 보관함
createApp(App).mount('#app')
그냥 자주 쓰는 라이브러리가 있으면 main.js에 박으셈
이제 모든 컴포넌트에서 emitt를 사용할수 있다.
다시 FilterBox로 돌아가보자
<template>
<div :class="필터 +' filter-item'" :style="`background-image:url(${이미지})`">
<slot></slot>
<button @click="fire"> 버튼 </button>
</div>
</template>
필터박스에서 클릭 이벤트를 하나 만들어 주고 fire라는 함수를 하나 설정해주자
methods : {
fire(){
this.emitter.emit('작명','데이터'); //이벤트 쏴준는겨 ㅋ
}
}
this.emitter.emit('작명','데이터'); 으로 발사
이제 수신하면댐ㅋ
app.vue에서 받는다고 가정해보자
mounted(){
this.emitter.on(' 작명', (a)=>{
console.log(a)
});
},
그럼 이제 저런 코드를 바탕으로 수신을 할수가 있음
근데 많으 쓰면 관리 하기가 너무 힘들어짐
그래서 대체품으로 vuex 라는게 있음ㅋ
필터 박스를 클릭시 app.vue로 필터명이 전송되어야 함
→ 그냥 emit ㄱㄱ
<template>
<div **@click="fire"** :class="필터 +' filter-item'" :style="`background-image:url(${이미지})`">
<slot></slot>
<button @click="fire"> 버튼 </button>
</div>
</template>
App.vue에도 필요하고 Container에도 필요함
→ 실제로 필터를 적용하고 발행할때도 필요하기 때문
둘다에서 필요하니 애초에 app.vue에 보내고 하향식으로 보내는 방식으로 하는게 좋을듯
fire(){
this.emitter.emit('박스클릭함',this.필터);
}
}
이름을 박스클릭함으로 전해주고 필터를 적용해야하니 필터 데이터를 보내주자
그럼 전송하는 코드를 보냈으니(fire) 수신하는 코드를 app.vue에서 작성해보자
→ app.vue가 더 상위 컴포넌트 이기 때문.
근데 … 강의에서는 걍 귀찮으니 Container에서 하라고 하네용..
data(){
return{
필터들 : [ "aden", "_1977", "brannan", "brooklyn", "clarendon", "earlybird", "gingham", "hudson",
"inkwell", "kelvin", "lark", "lofi", "maven", "mayfair", "moon", "nashville", "perpetua",
"reyes", "rise", "slumber", "stinson", "toaster", "valencia", "walden", "willow", "xpro2"],
선택한필터 : '',
}
},
mounted(){
this.emitter.on('박스클릭함',(a)=>{
this.선택한필터 = a
})
}
}
일단은 데이터바인딩을 하기 위한 그릇이 필요하니 Data에서 선택한필터 라는 데이터를 하나 생성해주자
그러고 mounted를 통해서 fire을 수신하는 코드를 작성해줌
이제 큰 사진을 보관하는 코드에 선택한필터 데이터를 데이터 바인딩 해주면 댐
<div :class="선택한필터" class="upload-image" :style="`background-image:url(${이미지})`"></div>
클래스명에 데이터 바인딩을 하기위해서는 : 형태로 넣어주기는 잊지말자
이런식으로 누를때마다 필터가 잘 적용됨!
<div :class="선택한필터" class="upload-image" :style="`background-image:url(${이미지})`"></div>
근데 글 작성 페이지에서도 이 적용된 필터가 그대로 가야하니 똑같이 데이터 바인딩 해주면된다.
응응… 잘된다.
이제 app.vue에서 발행한 화면에서도 똑같이 적용해야함
export default {
name: 'App',
data(){
return{
작성한글 : '',
게시물 : Postdata,
더보기 : 0,
step : 0,
이미지 : '',
선택한필터 : '',
}
},
mounted(){
this.emitter.on('박스클릭함',(a)=>{
this.선택한필터 = a
});
},
publish(){
var 내게시물 = {
name: "Kim Joo Hyun",
userImage: "https://picsum.photos/100?random=1",
postImage: this.이미지,
likes: 36,
date: "May 15",
liked: false,
content: this.작성한글,
filter: this.선택한필터,
};
똑같이 데이터 하나 만들어주고 mounted처리 해주고
발행 함수의 필터 부분에 선택한 필터 데이터를 바인딩 해주면 된다.