vue3学习(十)

编程入门 行业动态 更新时间:2024-10-26 14:30:49

vue3学习(十)

vue3学习(十)

文章目录

  • Provide 和 Inject
  • 兄弟组件通信Event Bus
    • Mitt库

Provide 和 Inject

provide 可以在祖先组件中指定我们想要提供给后代组件----子、孙等组件的数据或方法,而在任何后代组件中,我们都可以使用 inject 来接收 provide 提供的数据或方法。

父组件
<template><div class="App"><button>我是App</button><A></A></div>
</template><script setup lang='ts'>
import { provide, ref,readonly } from 'vue'
import A from './components/A.vue'
let flag = ref<number>(1)
provide('flag', flag) 父组件传递provide('flag', readonly(flag)) 这种传递方式子组件是无法修改数据的
</script><style>
.App {background: blue;color: #fff;
}
</style>
子组件
<template><div style="background-color: green;">我是B<button @click="change">change falg</button><div>{{ flag }}</div></div>
</template><script setup lang='ts'>
import { inject, Ref, ref } from 'vue'const flag = inject<Ref<number>>('flag', ref(1)) 子组件接收
const change = () => {flag.value = 2 子组件可以修改传递的值
}
</script><style>
</style>

注意:你如果传递普通的值是不具有响应式的 需要通过ref reactive 添加响应式。

如果不让后代组件修改数据可以在传递数据的时候加上readonly限制。


兄弟组件通信Event Bus

这个原理其实是运用了JS设计模式之发布订阅模式,通过一个中间件来处理。

 
type BusClass<T> = {emit: (name: T) => voidon: (name: T, callback: Function) => void
}
type BusParams = string | number | symbol 
type List = {[key: BusParams]: Array<Function>
}
class Bus<T extends BusParams> implements BusClass<T> {list: Listconstructor() {this.list = {}}emit(name: T, ...args: Array<any>) {let eventName: Array<Function> = this.list[name]eventName.forEach(ev => {ev.apply(this, args)})}on(name: T, callback: Function) {let fn: Array<Function> = this.list[name] || [];fn.push(callback)this.list[name] = fn}
}export default new Bus<number>()

Mitt库

Mitt是一个体积极小的第三方消息发布/订阅式JavaScript库,React、Vue均可以使用。

安装

  npm install --save mitt

main.ts 初始化

import { createApp } from 'vue'
import App from './App.vue'
import mitt from 'mitt'const Mit = mitt()//TypeScript注册
// 由于必须要拓展ComponentCustomProperties类型才能获得类型提示
declare module "vue" {export interface ComponentCustomProperties {$Bus: typeof Mit}
}const app = createApp(App)//Vue3挂载全局API
app.config.globalProperties.$Bus = Mitapp.mount('#app')

A组件派发(emit)

<template><div><h1>我是A</h1><button @click="emit1">emit1</button><button @click="emit2">emit2</button></div>
</template><script setup lang='ts'>
import { getCurrentInstance } from 'vue'
const instance = getCurrentInstance();
const emit1 = () => {instance?.proxy?.$Bus.emit('on-num', 100)
}
const emit2 = () => {instance?.proxy?.$Bus.emit('*****', 500)
}
</script><style>
</style>

B组件监听(on)

<template><div><h1>我是B</h1></div>
</template><script setup lang='ts'>
import { getCurrentInstance } from 'vue'
const instance = getCurrentInstance()
instance?.proxy?.$Bus.on('on-num', (num) => {console.log(num,'===========>B')
})
</script><style>
</style>
监听一个
instance?.proxy?.$Bus.on('on-num', (num) => {console.log(num,'===========>B')
})监听所有
instance?.proxy?.$Bus.on('*',(type,num)=>{console.log(type,num,'===========>B')
})移除监听事件
instance?.proxy?.$Bus.on('on-num',Fn)//listen
instance?.proxy?.$Bus.off('on-num',Fn)//unListen清空所有监听 
instance?.proxy?.$Bus.all.clear() 

更多推荐

vue3学习(十)

本文发布于:2023-12-08 10:50:17,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1672632.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!