上篇文章 【Vue】Vue3.0(十九)Vue 3.0 中一种组件间通信方式-自定义事件
🏡作者主页:点击!
🤖Vue专栏:点击!
⏰️创作时间:2024年11月11日12点23分
文章目录
-
-
- [一、mitt 在示例代码中的使用解释](#一、mitt 在示例代码中的使用解释)
- 二、新的`mitt`使用示例
-
一、mitt 在示例代码中的使用解释
在给定的代码中,mitt
库(这里假设emitter
是基于mitt
创建的实例)用于实现组件间的事件通信。
- 在
Child1.vue
中的使用
html
<button @click="emitter.emit('send - toy', toy)">玩具给弟弟</button>
这里使用emitter.emit
触发了一个名为send - toy
的事件,并将toy
的值作为参数传递。emitter
是从@/utils/emitter
引入的,它是基于mitt
创建的事件发射器。这意味着Child1
组件在按钮点击时,会发送一个事件,通知其他组件有玩具要传递的信息。
- 在
Child2.vue
中的使用
javascript
emitter.on('send - toy', (value: any) => {
toy.value = value;
});
onUnmounted(() => {
emitter.off('send - toy');
});
- `emitter.on('send - toy',...)`:通过`on`方法监听`send - toy`事件。当`send - toy`事件被触发时,回调函数会被执行,将接收到的值赋给`toy`。这样,`Child2`组件就能接收到`Child1`组件发送的玩具信息。
- `onUnmounted(() => { emitter.off('send - toy'); })`:在`Child2`组件卸载时,使用`off`方法解绑`send - toy`事件。这是一种良好的实践,可以防止内存泄漏和不必要的事件监听。
效果:
child1没有给child2的时候
给了之后:
二、新的mitt
使用示例
假设我们有一个简单的待办事项应用,有一个TodoList
组件和一个TodoItem
组件,当TodoItem
完成时,需要通知TodoList
更新完成事项的数量。
- 创建
emitter.js
(基于mitt
)
javascript
import mitt from'mitt';
export default mitt();
TodoItem.vue
组件
html
<template>
<div class="todo-item">
<input type="checkbox" v-model="isCompleted" @change="toggleCompleted">
<!-- 下面这行有一个坑的存在,这里需要判断父传过来的todo是否为空,如果为空的时候不去取text,否则的话会报错 -->
<span v-if="todo">{{ todo.text }}</span>
</div>
</template>
<script setup lang="ts" name='todoItem'>
import emitter from '@/utils/emitter';
import { ref } from 'vue';
interface Todo {
text: String;
}
const props = defineProps<{
todo: Todo;
}>();
const isCompleted = ref(false);
const toggleCompleted = () => {
//这里会根据子项的选中与否的状态来触发父组件中的完成数量的增减
if (isCompleted.value) {
emitter.emit('todo-completed');
}else{
emitter.emit('undo-completed');
}
};
</script>
<style scoped>
.todo-item {
display: flex;
align-items: center;
margin: 5px;
}
</style>
在TodoItem
组件中,当复选框的状态变为完成(isCompleted
为true
)时,通过emitter.emit('todo - completed')
触发todo - completed
事件。
TodoList.vue
组件
html
<template>
<div class="todo-list">
<h2>待办事项列表</h2>
<TodoItem v-for="todo in todos" :key="todo.text" :todo="todo" />
<p>已完成事项数量: {{ completedCount }}</p>
</div>
</template>
<script setup lang="ts" name='todoList'>
import TodoItem from './TodoItem.vue';
import emitter from '@/utils/emitter';
import { ref } from 'vue';
const todos = ref([
{ text: '学习 Vue3' },
{ text: '阅读书籍' },
{ text: '锻炼身体' }
]);
const completedCount = ref(0);
//监听子组件触发的数量增加
emitter.on('todo-completed', () => {
completedCount.value++;
});
//监听子组件触发的数量减少
emitter.on('undo-completed', () => {
completedCount.value--;
});
</script>
<style scoped>
.todo-list {
background-color: lightgray;
padding: 10px;
}
</style>
在TodoList
组件中,使用emitter.on('todo - completed',...)
监听todo - completed
事件。每当TodoItem
组件中的某个待办事项完成并触发该事件时,completedCount
就会增加,从而更新已完成事项的数量显示。这样,通过mitt
实现了组件之间的事件通信,让TodoList
组件能够对TodoItem
组件的状态变化做出响应。
效果