vue--Mitt全局事件的发布和订阅与取消订阅(也就是跨组件通讯)
Mitt
Mitt是一个体积极小的第三方消息发布/订阅式JavaScript库
官方文档是与框架无关的,所以这个玩意其实React、Vue都可以用
安装mitt库 1 npm i mitt -S 使用mitt库 在单独的文件暴露出事件总线对象 // mitt库默认导出的是一个函数,我们需要执行它从而得到事件总线的对象 /* eventbus.js */ import mitt from 'mitt' const emitter = mitt() export default emitter 在指定组件中导入并使用它 复制代码 /* one.vue */ // 模板代码 <button @click="send">sure</button> // 导入事件总线 import emitter from "@/utils/eventbus.js"; // methods代码 send(){ // 触发自定义总线why,并传入一个对象 emitter.emit("updateList",{name:'bbv',age:22}) } 复制代码 复制代码 /* two.vue */ // 导入事件总线 import emitter from "./utils/eventbus.js"; // 注册updataList事件总线 created(){ emitter.on("updateList",msg=>{ console.log(msg) }) } 复制代码 取消所有的mitt事件 emitter.all.clear() 取消指定的mitt事件 // 回调定义在外部,类似于setTimeout function onXxx(){} emitter.on('foo',onXxx) //监听 emitter.off('foo',onXxx) //取消监听
安装 在项目的根目录下执行: $ npm i mitt --save 导入 在 src/下新建一个 bus.js文件,内容如下: /* bus.js */ import mitt from "mitt"; const bus = {} const emitter = mitt() bus.$on = emitter.on bus.$off = emitter.off bus.$emit = emitter.emit export default bus 这段代码引入了mitt,并利用mitt()构造器生成了一个emit实例,同时把 on、off和 emit方法赋值给了空对象 bus,作为静态方法 打开 src/main.js内容如下: /* main.js */ import { createApp } from 'vue' import App from './App.vue' createApp(App).mount('#app') 改造 main.js,导入刚才的 bus对象,并挂载到全局 改造后的 main.js: /* main.js */ import { createApp } from 'vue' import App from './App.vue' import bus from './bus' const app = createApp(App) app.config.globalProperties.$bus = bus app.mount('#app') 使用 这里,我们在父、子组件间通过刚才挂载的全局对象 $bus来进行事件传递,并使用Vue3新增的 reactive来实现一个响应式组件 改造 改造默认模板里的 src/App.vue和 src/components/HelloWorld.vue,改造后的 App.vue: <template> <img alt="Vue logo" src="./assets/logo.png"> <button>这是一个按钮</button> <HelloWorld msg="Welcome to Your Vue.js App"/> </template> <script> import HelloWorld from './components/HelloWorld.vue' export default { name: 'App', components: { HelloWorld }, methods: { handleClick() { this.$bus.$emit('click') } } } </script> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style> 改造后的 HelloWorld.vue: <template> <div class="hello"> <h1>{{ msg }}</h1> <p> For a guide and recipes on how to configure / customize this project,<br/> check out the <a href="https://cli.vuejs.org" target="_blank" rel="noopener" >vue-cli documentation</a >. </p> <h3>Installed CLI Plugins</h3> <ul> <li v-for="i in links" :key="i.text"> <a href={{i.link}} target="_blank" rel="noopener">{{ i.text }}</a> </li> </ul> <h3>Essential Links</h3> <ul> <li> <a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a> </li> <li> <a href="https://forum.vuejs.org" target="_blank" rel="noopener" >Forum</a > </li> <li> <a href="https://chat.vuejs.org" target="_blank" rel="noopener" >Community Chat</a > </li> <li> <a href="https://twitter.com/vuejs" target="_blank" rel="noopener" >Twitter</a > </li> <li> <a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a> </li> </ul> <h3>Ecosystem</h3> <ul> <li> <a href="https://router.vuejs.org" target="_blank" rel="noopener" >vue-router</a > </li> <li> <a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a> </li> <li> <a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener" >vue-devtools</a > </li> <li> <a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener" >vue-loader</a > </li> <li> <a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener" >awesome-vue</a > </li> </ul> </div> </template> <script> import {reactive} from "vue"; export default { name: "HelloWorld", props: { msg: String, }, setup() { const links = reactive([ {link: 'https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel', text: 'babel'}, {link: 'https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint', text: 'eslint'} ]) const add = () => links.push({ link: 'https://github.com/developit/mitt', text: 'mitt' }) return {links, add} }, mounted() { this.$bus.$on("click", this.add); }, }; </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> h3 { margin: 40px 0 0; } ul { list-style-type: none; padding: 0; } li { display: inline-block; margin: 0 10px; } a { color: #42b983; } </style>

浙公网安备 33010602011771号