【问题标题】:Vuejs custom Modal event bus is not firingVuejs自定义模态事件总线未触发
【发布时间】:2021-09-26 16:37:03
【问题描述】:

我在 vuejs 中创建了自己的自定义 Modal 插件,以添加到我的 Laravel 8 应用程序中。我面临的问题是打开模式。

我在 app.js 文件中创建了插件

const Modal = {
    install (Vue) {
        this.event = new Vue()

        Vue.prototype.$modal = {
            show (modal, params = {}) {
                Modal.event.$emit('show', modal, params)
            },
            $event: this.event
        }
    }
}

Vue.use(Modal)

我为我的模态创建了两个 vue 组件

<!-- AppModal //-->
<template>
    <transition name="modal">
        <div v-if="visible">
            <div class="app-modal" @click.prevent="$modal.hide(name)"></div>
            <div class="app-modal-inner">
                <a href="" @click.prevent="$modal.hide(name)">close</a>
                <slot name="body" :params="params"/>
            </div>
        </div>
    </transition>
</template>

<script>
export default {
    name: "AppModal",
    data () {
        return {
            params: {},
            visible: false,
        }
    },
    props: {
        name: {
            required: true,
            type: String,
        }
    },
    methods: {
        setVisible () {
            this.visible = true
        },
        setHidden () {
            this.visible = false
        }
    },
    beforeMount() {
        this.$modal.$event.$on('show', (modal, params) => {
            if (this.name !== modal) {
                return
            }

            this.params = params

            this.setVisible()
        })
    },
}
</script>

<!-- AppNonMemberRegisterModal //-->
<template>
    <app-modal name="register">
        <template slot="header">
            <h1 class="text-lg-left text-4xl border border-b-2">Register Now</h1>
        </template>
        <template slot="body" slot-scope="{ params }">
            <p>You need to register in order to share, comment and like on the site</p>
        </template>
    </app-modal>
</template>

<script>
import AppModal from "../AppModal";

export default {
    name: "AppNonMemberRegisterModal",
    components: { AppModal },
}
</script>

我在触发事件的地方导入了AppNonMemberRegisterModal,并且我有以下点击事件:@click.prevent="$modal.show('register')"

当达到以下代码 Modal.event.$emit('show', modal, params) 我在我的 cnosole 中收到以下错误消息 console.log(Modal)

【问题讨论】:

  • 我不确定你是否必须做this.event = new Vue(),试试this.event = Vue,如果你有新的错误告诉我
  • 感谢您的回复,通过设置this.event = Vue 我得到以下类型错误:Modal.event.$emit is not a function
  • 我刚刚阅读了关于插件的documentation(因为我以前从未这样做过,而且我没有看到任何new Vue() 或类似的东西,这没有任何意义。当你这样做时。 $modal.$event.$on` 你期望$event 是什么?问题出在你的Vue.prototype.$modal 定义中,你已经将show 定义为一个函数(这是正确的),$event,而你正在使用$modal.hide,但我没有看到它在prototype 中定义,因此稍后会出现错误,因为它没有定义。
  • 另外,您使用的是 Vue 2 还是 3?
  • 已经定义了隐藏函数但是我这里没有添加。我正在使用 vue 3

标签: laravel vue.js vuejs3 event-bus


【解决方案1】:

Vue 3 删除了事件 API(即$on$off 等)。 migration guide recommends using tiny-emitter to create your own event bus。该示例显示了如何创建全局总线,但您的插件似乎只需要一个本地总线,您可以这样创建:

// eventBus.js
import Emitter from 'tiny-emitter'

export function createEventBus() {
  const emitter = new Emitter()
  return {
    $on: (...args) => emitter.on(...args),
    $once: (...args) => emitter.once(...args),
    $off: (...args) => emitter.off(...args),
    $emit: (...args) => emitter.emit(...args)
  }
}

然后在你的插件中,create a global with app.config.globalProperties,指的是本地创建的事件总线:

// myPlugin.js
import { createEventBus } from './eventBus'

export default {
  install(app) {
    const eventBus = createEventBus()

    app.config.globalProperties.$modal = {
      show (modal, params = {}) {
        eventBus.$emit('show', modal, params)
      },
      $event: eventBus
    }
  }
}

并安装它:

// main.js
import { createApp } from 'vue'
import App from './App.vue'
import myPlugin from './myPlugin'

createApp(App).use(myPlugin).mount('#app')

另外请注意,AppRegisterModal.vue 中的插槽使用情况需要更新为最新语法(v-slot# 简写):

<app-modal name="register">
  <!--
  <template slot="header">
  -->
  <template #header>

  <!--
  <template slot="body" slot-scope="{ params }">
  -->
  <template #body="{ params }">
</app-modal>

demo

【讨论】:

    猜你喜欢
    • 2019-09-09
    • 1970-01-01
    • 1970-01-01
    • 2011-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-08
    • 2018-01-12
    相关资源
    最近更新 更多