本文介绍了Vue 3 - 从插槽内的子组件发出事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在考虑升级到 v3,但很失望地看到内联模板已被删除.因此,我正在尝试转换为使用作用域插槽.

I'm looking at upgrading to v3 and was disappointed to see inline-template has been removed. Therefore I'm trying to convert to use a scoped slot instead.

我定义了以下列表组件:

I have defined the following list component:

<template>
    <slot :items="filteredItems" :page="page" :totalPages="totalPages" :onPageChanged="onPageChanged"></slot>
</template>

<script>
    export default {
        props: {
            items: {
                type: Array
            },
            initialPage: {
                type: Number,
                default: 1,
            },
            pageSize: {
                type: Number,
                default: 10
            }
        },
        beforeCreate() {
            this.page = this.initialPage;
        },
        computed: {
            filteredItems() {
                return this.items.slice((this.page - 1) * this.pageSize, this.page * this.pageSize);
            },
            totalPages() {
                return Math.ceil(this.items.length / this.pageSize);
            }
        },
        methods: {
            onPageChanged(page) {
                console.log('Page changed!!!');

                this.page = page;
            }
        }
    };
</script>

是这样称呼的:

<list :items="[ { foo: 'A' }, { foo: 'B' }, { foo: 'C' } ]" :page-size="2" #="{ items, page, totalPages, onPageChanged }">
    <ul class="list-group">
        <li class="list-group-item" v-for="item in items">{{ item.foo }}</li>
    </ul>
    <pager :page="page" :total-pages="totalPages" @pageChanged="onPageChanged"></pager>
</list>

这是寻呼机组件:

<template>
    <ul class="pagination">
        <li class="page-item" v-if="hasPreviousPage"><a href="#" @click="changePage(1)" class="page-link">&laquo;</a></li>
        <li class="page-item" v-if="hasPreviousPage"><a href="#" @click="changePage(page - 1)" class="page-link">&#8249;</a></li>
        <li v-for="page in pages" :class="['page-item', { active: page.isActive }]"><a href="#" @click="changePage(page.name)" class="page-link">{{ page.name }}</a></li>
        <li class="page-item disabled" v-if="page < totalPages - 2"><span class="page-link"> ... </span></li>
        <li class="page-item" v-if="page < totalPages - 2"><a href="#" @click="changePage(totalPages)" class="page-link">{{ totalPages }}</a></li>
        <li class="page-item" v-if="hasNextPage"><a href="#" @click="changePage(page + 1)" class="page-link">&#8250;</a></li>
        <li class="page-item" v-if="hasNextPage"><a href="#" @click="changePage(totalPages)" class="page-link">&raquo;</a></li>
    </ul>
</template>

<script>
    export default {
        props: {
            page: {
                type: Number,
                required: true
            },
            totalPages: {
                type: Number,
                required: true
            }
        },
        computed: {
            hasPreviousPage() {
                return this.page > 1;
            },
            hasNextPage() {
                return this.page < this.totalPages;
            },
            pages() {
                const range = [];

                for (let i = this.page <= 2 ? 1 : this.page - 2; i <= (this.page >= this.totalPages - 2 ? this.totalPages : this.page + 2); i++) {
                    range.push({
                        name: i,
                        isActive: this.page == i
                    });
                }

                return range;
            }
        },
        methods: {
            changePage(page, e = event) {
                e.preventDefault();

                // Trigger the page changed event.
                this.$emit('pageChanged', page);
            }
        }
    };
</script>

但是,每当我尝试更改页面时,都会调用 changePage 方法,该方法会发出 pageChanged 事件,但它不会调用 onPageChanged 列表组件中的方法.

However whenever I try to change the page, the changePage method is invoked which emits the pageChanged event, but it doesn't invoke the onPageChanged method within the list component.

如果有人能告诉我我做错了什么,我将不胜感激.谢谢

I'd appreciate if someone could show me what I'm doing wrong. Thanks

推荐答案

事件名称应以kebab-case格式书写如下:

The event name should be written in kebab-case format as follows :

this.$emit('page-changed', page);

并像 @page-changed="onPageChanged

这篇关于Vue 3 - 从插槽内的子组件发出事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-12 17:14