[Vue.js] mitt (Vue3에서 컴포넌트간 통신방법)
2021. 7. 4. 20:54ㆍ프론트엔드/Vue.js
728x90
[에러내용] Vue3에서 EventBus를 적용해보려 했는데, 계속 $on관련 에러발생
Vue3마이그레션(사용)을 위해 알아둘 점
Vue3에서는 $on, $once, $off를 사용하지 않음
$emit은 parent componet에 부착되어 trigger event handler API로 여전히 사용됨
'EventBus'는 Vue가 추천하는 공식적인 방법이 아님
'mitt'이라는 외부라이브러리를 이용하여 EventBus구현
mitt
외부 라이브러리
mitt라이브러리는 커스텀이벤트를 만들어 송출, 수신할 수 있게 해줌
기존의 eventBus 대체하여 사용 가능
mitt사용예시
나의 경우, 'TodoInput.vue'에서 todoInput이라는 입력값을 입력받고 형제컴포넌트인 'TodoList.vue'로 넘겨서 dynamicLists로 todoInput값을 추가시키는 것이 목적
<template>
<div>
<TodoInput></TodoInput>
<TodoList></TodoList>
</div>
</template>
<script>
import TodoInput from './components/TodoInput.vue';
import TodoList from './components/TodoList.vue';
export default {
name: 'App',
components: {
TodoInput
,TodoList
}
}
</script>
<style>
</style>
1. mitt 설치(mitt은 외부라이브러리이므로 별도 설치필요)
>npm install --save mitt
2. main.js(다른 js파일 작성해도 무관) emitter등록
Vue의 globalProperties로 emitter를 등록
import { createApp } from 'vue'
import App from './App.vue'
import mitt from 'mitt'
const emitter = mitt();
const app = createApp(App);
app.config.globalProperties.emitter = emitter
app.mount('#app')
//이렇게 사용불가
// const emitter = mitt();
// createApp(App).config.globalProperties.emitter = emitter
// createApp(App).mount('#app')
3. 이벤트 보내기
<script>
export default{
methods:{
enterKeyFunction(){
this.emitter.emit('addTodoInput', this.todoInput)
this.todoInput = '';
}
}
}
</script>
TodoInput.vue 전체소스
<!-- 할 일 입력 -->
<template>
<div class="todoapp">
<h1>TODOS</h1>
<input
id="new-todo-title"
class="new-todo"
placeholder="할일을 추가해주세요"
autofocus
@keyup.enter="enterKeyFunction"
v-model="todoInput"
/>
</div>
</template>
<script>
export default {
data(){
return{
todoInput :'',
}
},
methods:{
enterKeyFunction(){
this.emitter.emit('addTodoInput', this.todoInput)
this.todoInput = '';
}
}
}
</script>
4. 이벤트 받기
<script>
export default{
mounted(){
this.emitter.on('addTodoInput',this.addTodoInputFunction)
},
}
</script>
TodoList.vue 전체소스
<template>
<div class="todoapp">
<ul id="todo-list" class="todo-list" v-if="showTodoList">
<li v-for="(list, index) in dynamicLists[0]" :key="index">
<div class="view">
<label class="label">{{list.item}}</label>
</div>
<input class="edit" value="새로운 타이틀" />
</li>
</ul>
</div>
</template>
<script>
export default {
data(){
return {
dynamicLists:[{}],
now:"0000년00월00일00시00분00초", //입력시간세팅
}
},
created(){
let totCnt = 0;
this.localStorageLength = localStorage.length
for(let i=0; i<this.localStorageLength; i++){
if(localStorage.key(i).indexOf('loglevel:') === -1){
this.dynamicLists[0][localStorage.key(i)] = JSON.parse(localStorage.getItem(localStorage.key(i)));
if( this.dynamicLists[0][localStorage.key(i)].completed){
this.isCompletedArr[localStorage.key(i)] = true;
}
totCnt++;
}
}
this.totalCount = totCnt;
},
mounted(){
this.emitter.on('addTodoInput',this.addTodoInputFunction)
},
methods:{
getCurrTime(){
let date = new Date();
this.now = `${date.getFullYear()}년 ${date.getMonth()+1}월 ${date.getDate()}일 ${date.getHours()}시 ${date.getMinutes()}분 ${date.getSeconds()}초 `;
},
addTodoInputFunction(todoInput){
this.getCurrTime();
if(todoInput.trim()!=="" && !localStorage.getItem(todoInput) ){
let value ={
item:todoInput
,completed:false
,time:this.now
};
localStorage.setItem(todoInput,JSON.stringify(value));
this.dynamicLists[0][todoInput] = JSON.parse(localStorage.getItem(todoInput));
}
},
}
</script>
728x90
'프론트엔드 > Vue.js' 카테고리의 다른 글
[Vue.js] Vue 라이프사이클 훅 (0) | 2021.07.06 |
---|---|
[Vuejs] 화살표 함수사용의 편리성 (0) | 2021.05.22 |
[Vuejs] Vue-CLI 프로젝트 생성 (0) | 2021.05.22 |
[Vuejs] 체크박스 한개만 체크 되도록 구현 (0) | 2021.05.22 |
[Vuejs] methods/ computed/ whatch (0) | 2021.05.12 |