Javascript Vue将同一组件导入两次/Vue事件仅从子级导入到根级,而不是父级

Javascript Vue将同一组件导入两次/Vue事件仅从子级导入到根级,而不是父级,javascript,vue.js,ecmascript-6,vue-component,laravel-blade,Javascript,Vue.js,Ecmascript 6,Vue Component,Laravel Blade,我拥有的 我正在导入相同的组件两次。此组件用于显示包含集合的下拉列表。 选择下拉列表中的项目时,将触发一个事件。 该组件在list.js和BulkActions.vue中导入 问题 选择下拉列表中的集合时将触发事件。然后,它使用$emit触发一个事件。不知何故,此事件仅在list.blade.php中捕获,而不在BulkActions.vue中捕获。 对于两个下拉列表(从同一组件加载),应该有不同的行为。 我不知道为什么会发生这种情况,也不知道为什么这件事只在我的根上发生 我尝试过的 我试图在H

我拥有的

我正在导入相同的组件两次。此组件用于显示包含集合的下拉列表。 选择下拉列表中的项目时,将触发一个事件。 该组件在
list.js
BulkActions.vue
中导入

问题


选择下拉列表中的集合时将触发事件。然后,它使用
$emit
触发一个事件。不知何故,此事件仅在
list.blade.php中捕获,而不在
BulkActions.vue中捕获。
对于两个下拉列表(从同一组件加载),应该有不同的行为。
我不知道为什么会发生这种情况,也不知道为什么这件事只在我的根上发生

我尝试过的

我试图在HTML中传递一个额外的
属性
,以获得一个“变量事件名称”,但这不起作用。我也尝试过各种导入组件的方法

有人知道如何解决这个问题吗

文件

list.blade.php

    <div class="media-list-navbar mt-3 mb-3">
        <shown-results :text="resultText"></shown-results>

        <search-bar @update-filters="updateFilters"></search-bar>

        <document-types @update-filters="updateFilters"></document-types>

        <collection-dropdown eventname="update-filters"
                             @update-filters="updateFilters"></collection-dropdown>


        <div class="clearfix"></div>
    </div>

    <bulk-actions @select-all="selectAll"
                  @deselect-all="deselectAll"
                  :items="items"
                  :multiselect="multiSelect"></bulk-actions>
list.js

import MediaItem from '../components/MediaItem';
import UploadModal from '../components/media/UploadModal';
import ItemDetail from '../components/media/ItemDetail';
import ShownResults from '../components/media/list/ShownResults';
import SearchBar from '../components/media/list/SearchBar';
import DocumentTypes from '../components/media/list/DocumentTypes';
import {default as CollectionDropdown} from '../components/media/list/Collections';
import Order from '../components/media/list/Order';
import BulkActions from '../components/media/list/BulkActions';

if (document.getElementById('media-list')) {
    const mediaList = new Vue({
        el: '#media-list',
        components: {
            MediaItem,
            ShownResults,
            SearchBar,
            UploadModal,
            ItemDetail,
            DocumentTypes,
            CollectionDropdown,
            Order,
            BulkActions
        },
[...]
Collections.vue

<template>
    <div class="multiselect-list-navbar mt-3 mb-3" v-if="multiselect">
        <div class="float-left">
            <button type="button"
                    class="btn btn-outline-secondary"
                    @click="$emit('deselect-all')">
                <i class="fas fa-fw fa-times"></i> {{ Lang.get('media/item.index.list.multi-select.deselect-all') }}
            </button>
            <button type="button"
                    class="btn btn-outline-secondary"
                    @click="$emit('select-all')">
                <i class="fas fa-fw fa-check"></i> {{ Lang.get('media/item.index.list.multi-select.select-all') }}
            </button>
        </div>

        <bulk-collection
            @update-filters="doSomething"></bulk-collection>
        <div class="clearfix"></div>
    </div>
</template>

<script>
    export default {
        name: "Bulk",
        props: {
            multiselect: Boolean,
            items: Array
        },
        components: {
            'bulk-collection': () => import('./Collections')
        },
        methods: {
            doSomething() {
                console.log(this.items)
            }
        }
    }
</script>

<style scoped>

</style>

<template>
    <div class="dropdown float-left">
        <button class="btn btn-secondary dropdown-toggle"
                type="button"
                data-toggle="dropdown">
            {{ Lang.get('media/item.index.list.filters.collections.title') }}
        </button>
        <div class="dropdown-menu" ref="collectionDropdown">
            <div class="dropdown-item no-pseudo">
                <input type="search"
                       class="form-control"
                       name="search"
                       :placeholder="Lang.get('media/item.index.list.filters.collections.filter')"
                       v-model="query"
                       @keyup="search">
            </div>
            <div class="dropdown-item last-item no-pseudo">
                <alert type="warning">
                    <template v-slot:body>
                        {{ Lang.get('media/item.index.list.filters.collections.none-filter') }}
                    </template>
                </alert>
            </div>
            <div v-for="item in list"
                 class="dropdown-item"
                 v-if="!item.hidden">
                <span class="custom-control custom-checkbox">
                    <input type="checkbox"
                           class="custom-control-input"
                           name="collection[]"
                           :checked="item.checked"
                           :id="item.slug"
                           :value="item.id"
                           @change="selectItem">
                    <label class="custom-control-label" :for="item.slug">
                        {{ item.name }}
                    </label>
                </span>
            </div>
        </div>
    </div>
</template>

<script>
    import Alert from '../../partials/Alert';

    export default {
        name: "Collections",
        components: {
            Alert
        },
        data() {
            return {
                displayAmount: 10, // amount of items displayed without search
                list: [],
                query: ''
            }
        },
        computed: {
            /**
             * Return an array of selected items only
             */
            checked() {
                return this.list.filter(item => {
                    return item.checked === true;
                })
            }
        },
        methods: {
            /**
             * Mark an item as selected
             */
            selectItem(e) {
                let selectedId = e.target.value;

                this.markItem(selectedId);
            },
            /**
             * Mark an item from the list as selected
             *
             * @param {Number} itemId
             */
            markItem(itemId) {
                this.list.forEach(item => {
                    if (item.id === parseInt(itemId)) {
                        item.checked = !item.checked;
                    }
                });

                this.$emit('update-filters', {
                    props: this.checked.map(item => item.id).join(',')
                });
            },
            /**
             * Search in the current URL for collection ids
             */
            markItemsFromUrl() {
                let urlParams = new URLSearchParams(window.location.search);

                if (urlParams.has('collection')) {
                    let urlFilters = urlParams.get('collection').split(','); // split url parameters

                    urlFilters.forEach(itemId => {
                        this.markItem(itemId);
                    });
                }
            },
        },
        mounted() {
            this.fetchList();
            this.markItemsFromUrl();

            /**
             * Prevent Bootstrap dropdown from closing after clicking inside it
             */
            $(this.$refs.collectionDropdown).on('click.bs.dropdown', function (e) {
                e.stopPropagation();
            });
        }
    }
</script>

{{Lang.get('media/item.index.list.filters.collections.title')}

“不知何故,此事件仅在list.blade.php中捕获,而不在BulkActions.vue中”这就是它应该如何工作的。也许我没听清你的问题。使用
$emit
时,您告诉父vue组件必须从子vue组件执行某些操作。我看不出您在哪里两次导入同一组件。我在
list.blade.php
中看到了
Collections
,这是一个组件,在
BulkActions.vue
中看到了另一个组件。@对不起,我已经更新了我的问题。我现在也在其中添加了
Collections.vue
文件。我也注意到我的
BulkActions.vue
中仍然有一些测试代码,所以我也更新了该事件侦听器。@KaleshKaladharan我也这么认为,但在我的
BulkActions.vue
中没有捕捉到该事件。我添加了一个GIF动画来显示正在发生的事情。您是否尝试避免在
BulkActions
上导入动态组件?更新您的
doSomething
以实际打印
事件
,而不是道具
this.items