1 “你日渐平庸,甘于平庸,将继续平庸。”——《以自己喜欢的方式过一生》
2. “总是有人要赢的,那为什么不能是我呢?”——科比·布莱恩特
3. “你那么憎恨那些人,和他们斗了那么久,最终却要变得和他们一样,人世间没有任何理想值得以这样的沉沦作为代价。”——马尔克斯《百年孤独》
4. “如果结果不如你所愿,就在尘埃落定前奋力一搏。”——《夏目友人帐》
5. “人有逆天之时,天无绝人之路。”——《醒世恒言》
6. “有些事不是看到了希望才去坚持,而是因为坚持才会看到希望。”——《十宗罪》
7. “维持现状意味着空耗你的努力和生命。”——纪伯伦
一. 概述
在前端编程中(这里重点指的是WEB端编程),事件的处理是比较普遍的,如:单击、失焦、监听等,这里我们不一一的展开来说,这些都比较简单。而本次重点对 Vue 编程中的 “emit 和 依赖注入provide/inject” 的使用进行重点说明。思考下:为啥重点说它两个,(不说他两你写什么,说点其他的不行, …小学生 )
在本文开始之前,我们来回顾下在vue 中父子组件交互的方式有哪些? 10种(正统), 11(使用了三方库)?
1、父组件通过子组件的props属性,传值给子组件;
2、子组件通过$emit调用父组件的方法,传值给父组件;思考下emit原理?
3、父组件provide传递孙子组件inject接收;
4、父组件通过$refs获取子组件的数据或者方法; 不安全不建议但是爽,用就对了
5、子组件通过$parent获取父组件数据或者方法; 不安全不建议但是爽,用就对了
6、组件之间通过 a t t r s 和 attrs和 attrs和listeners透传,注意($listeners 对象在 Vue 3 中已被移除。事件监听器现在是 $attrs 的一部分)
7、事件总线event-bus
8、vue-router传值
9、vuex传值
10、slot作用域传值;
11、其他的组件库不要说,如:emitter.js,emtt等,说了的感觉知识面不太行
二. Emit
1. 概念
emit/emit是一个强大的工具,它使得事件能够在Vue组件层次结构中传播。在Vue.js中,$emit是一个实例方法,用于触发当前实例上的事件。这些事件可以被父级组件监听并作出响应。
重点:父子组件之间通信,非父子不可?(思考下)
2. 看个代码
- ParentComponent .vue
<!-- 父组件 -->
<script setup>
import ChildComponent from './ChildComponent.vue';const handleUpdate = (data) => {console.log('更新事件触发:', data);
};
</script><template><ChildComponent @update="handleUpdate" />
</template>
- ChildComponent .vue
<!-- 子组件 -->
<script setup>
import { defineEmits } from 'vue';// 定义触发的事件及其数据类型
const emit = defineEmits(['update']);// 触发事件
const handleUpdate = () => {emit('update', { id: 1, name: 'Vue 3' });
};
</script><template><button @click="handleUpdate">更新</button>
</template>
3. 原理
当你在子组件中调用 $emit 函数时,Vue 会查找该组件的父组件,并查看父组件是否监听了你触发的事件。如果父组件监听了该事件,那么它就会调用与该事件相关联的回调函数,并将你传递的数据作为参数传递给这个回调函数。这个过程是同步的,意味着一旦你调用了 $emit,父组件中的回调函数就会立即被调用。
三. Provide / Inject
1. 概念
provide 和 inject 是 Vue 3 提供的一种机制,主要用于在 祖先组件 和 后代组件 之间传递数据,尤其适用于跨级传值。重点(跨级组件通信)
2. 原理
来张图:
图的意思说明:
在创建vue组件实例时,子组件的provides属性对象会直接使用父组件的provides属性对象。如果在子组件中使用了provide函数,那么会以父组件的provides属性对象为原型创建一个新的provides属性对象,并且将provide函数中注入的内容塞到新的provides属性对象中,从而形成了原型链。
在孙子组件中,他的parent就是子组件。会直接使用他的父组件的provides属性对象,所以这里的子组件是直接使用的是父组件中的provides属性对象。所以在孙子组件中可以直接使用inject函数拿到父组件中注入的内容。
3. 使用方式
import { provide } from 'vue';export default {setup() {provide('message', 'Hello from parent');}
}
import { provide } from 'vue';export default {setup() {provide('message', 'Hello from parent');}
}
四. Eitt.js
1. 概念
mitt是一个小巧且快速的TypeScript实现的EventEmitter 3封装库,专门用于Vue 3应用中的组件通信。在Vue 2.x中,通常使用EventBus进行组件间的通信,但在Vue 3.x中,推荐使用mitt作为替代方案。
这个说明下:兄弟组件通信;当然使用provide/inject 包含在一个顶级组件中也可以实现,你要是说:vuex,vue-router pinia也能实现,你简直就是聪明的不行!
2. 使用
npm install mitt
import mitt from 'mitt'const emitter = mitt()// listen to an event
emitter.on('foo', e => console.log('foo', e) )// listen to all events
emitter.on('*', (type, e) => console.log(type, e) )// fire an event
emitter.emit('foo', { a: 'b' })// clearing all events
emitter.all.clear()// working with handler references:
function onFoo() {}
emitter.on('foo', onFoo) // listen
emitter.off('foo', onFoo) // unlisten
简洁的不止一点。