简体   繁体   English

为什么我不能在 vue.js 中触发自定义事件?

[英]Why cant' I trigger custom events in vue.js?

I have a local database that will be updated with pusher.我有一个本地数据库,将使用 pusher 进行更新。 This database is stored in JSON and the component will load and filter out what is not needed, making it impossible to add a watcher to the raw data.该数据库存储在 JSON 中,组件将加载并过滤掉不需要的内容,因此无法向原始数据添加观察者。

My idea (please advice me if there are better solution) was to add a listener for a custom event, then trigger this event when the DB is updated.我的想法(如果有更好的解决方案请告诉我)是为自定义事件添加一个侦听器,然后在更新数据库时触发此事件。 The only event I'm able to trigger is 'CLICK', with a simple $('.vue-template').trigger('click');我能够触发的唯一事件是'CLICK',带有一个简单的$('.vue-template').trigger('click');

This is paired with a simple @click="doSomething" on the element I chose as my target.这与我选择作为目标的元素上的简单@click="doSomething"配对。

This is not ideal because I don't want to fetch the data on any click, but only when the DB is updated, so I've tried @customevent="doSomething" but it doesn't work这并不理想,因为我不想在任何点击时获取数据,但只有在更新数据库时,所以我尝试@customevent="doSomething"但它不起作用

Any help?有什么帮助吗?

EDIT: More code编辑:更多代码

<template>
    <div class="listen listen-database-teachers"
         @dbupdate="testAlert">
        <span v-for="teacher in teachers"
              class="pointer btn btn-sm btn-default destroy-link"
              :data-href="computedHref(teacher)"
              :data-person="personIdentifier(teacher.person)"
              :data-personid="teacher.person_id">
        {{ personIdentifier(teacher.person) }} <span class="glyphicon glyphicon-remove"></span>
        </span>
    </div>
</template>

<script>
    export default {
        props: ['circleId'],
        data () {
            return {
                loading: false,
                teachers: null,
                error: null
            }
        },
        created () {
            // fetch the data when the view is created and the data is
            // already being observed
            this.fetchData();
        },
        methods: {
            fetchData() {
                this.error = this.teachers = this.categories = null;
                this.loading = true;

                var teachers = $(window).localDatabase('teachers', $(window).planner('currentSchoolId'));

                var searchCircle = this.circleId,
                    filtered_teachers = [];
                $.each(teachers, function(index, teacher){
                    if(teacher.membership_id == searchCircle)
                        filtered_teachers.push(teacher);
                });
                this.teachers = filtered_teachers.sort(function(a, b) {
                    return personIdentifier(a.person) > personIdentifier(b.person);
                });

                this.loading = false;
            },
            computedClass(teacher){
                return 'pointer btn btn-sm btn-default draggable membership-draggable-'+teacher.membership_id+' destroy-link'
            },
            computedHref(teacher){
                return window.links.destroy_membership
                        + '?association-id='+teacher.id
                        + '&circle-id='+teacher.circle_id;
            },
            testAlert: function(){
                return alert('success');
            }
        }
    }
</script>

EDIT 2: attempt to use BUS编辑 2:尝试使用 BUS

Remember that I use Laravel Mix.请记住,我使用 Laravel Mix。

app.js应用程序.js

window.vue_bus = new Vue();

master.js大师.js

function handleDatabaseUpdate(){
    window.vue_bus.$emit('refresh-data');
}

component零件

created () {
        // fetch the data when the view is created and the data is
        // already being observed
        this.fetchData();
        window.vue_bus.$on('refresh-data', this.testAlert());
    },

I've isolated the relevant bits of the code.我已经隔离了代码的相关位。 This executes testAlert() when the component is mounted, but it returns an error cbs[i] undefined when I call handleDatabaseUpdate() from browser console (on Firefox).这会在安装组件时执行testAlert() ,但是当我从浏览器控制台(在 Firefox 上)调用handleDatabaseUpdate()时,它会返回错误cbs[i] undefined

This is a case where I might use an event bus .这是我可能使用事件总线的情况。

A bus is created by simply creating an empty Vue.通过简单地创建一个空的 Vue 来创建总线。

const bus = new Vue()

In whatever function you have outside that is dealing with the database, you can emit an event using the bus.在处理数据库的任何外部功能中,您都可以使用总线发出事件。

function handleDatabaseUpdate(){
   //do database things
   bus.$emit("refresh-data")
}

Then in your component, add a handler.然后在您的组件中,添加一个处理程序。

created(){
    bus.$on("refresh-data", this.fetchData)
}

Since it looks like you are using single file components, you will have to make the bus available to both the component and your database manager.由于看起来您使用的是单个文件组件,因此您必须使总线对组件和数据库管理器都可用。 You can do that two ways.你可以通过两种方式做到这一点。 Quick and dirty, expose the bus on the window.又快又脏,把公共汽车暴露在窗户上。

window.bus = new Vue()

Second, you can create the bus in its own module and import the module into all the places you need to use it.其次,您可以在自己的模块中创建总线,并将模块导入到您需要使用它的所有地方。

bus.js总线.js

import Vue from "vue"

const bus = new Vue()
export default bus;

And in the code that deals with the database and in your component, import the bus.在处理数据库的代码和您的组件中,导入总线。

import bus from "/path/to/bus.js

That said, the reason you cannot listen to jQuery events in Vue is that jQuery uses it's own event system and Vue's listeners will never catch jQuery events.也就是说,你不能在 Vue 中监听 jQuery 事件的原因是 jQuery 使用它自己的事件系统,而 Vue 的监听器永远不会捕捉到 jQuery 事件。 If you still wanted to use jQuery, you could emit a custom event in jQuery and listen to that custom event also using jQuery.如果您仍然想使用 jQuery,您可以在 jQuery 中发出一个自定义事件,使用 jQuery 监听该自定义事件。 You would just have to dispatch the event to fetchData.您只需将事件分派给 fetchData。

created(){
    $("thing you sent the event from").on("refresh-data", this.fetchData)
}

Finally, this is also a case where a state management system (like Veux) would shine.最后,这也是状态管理系统(如 Veux)大放异彩的一个案例。 State management systems are intended for cases like this where state could be changing in many places and automatically reflecting those changes in the view.状态管理系统适用于这样的情况,其中状态可能在许多地方发生变化并自动在视图中反映这些变化。 There is, of course, more work implementing them.当然,实施它们还有更多工作要做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM