问题描述
我正在考虑升级到 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">«</a></li>
<li class="page-item" v-if="hasPreviousPage"><a href="#" @click="changePage(page - 1)" class="page-link">‹</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">›</a></li>
<li class="page-item" v-if="hasNextPage"><a href="#" @click="changePage(totalPages)" class="page-link">»</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 - 从插槽内的子组件发出事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!