Vue 3 - 从插槽内的子组件发出事件
Posted
技术标签:
【中文标题】Vue 3 - 从插槽内的子组件发出事件【英文标题】:Vue 3 - Emit event from child component within a slot 【发布时间】:2021-01-14 06:26:50 【问题描述】:我正在考虑升级到 v3,但看到 inline-template 已被删除感到很失望。因此,我正在尝试转换为使用作用域插槽。
我已经定义了以下列表组件:
<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
方法。
如果有人能告诉我我做错了什么,我将不胜感激。谢谢
【问题讨论】:
v3.vuejs.org/guide/component-custom-events.html#event-names "DOM 模板中的 v-on 事件监听器将自动转换为小写(由于 HTML 不区分大小写),因此@myEvent
将变为 @myevent
-- 使myEvent 无法收听。”
【参考方案1】:
事件名称应写成kebab-case
格式如下:
this.$emit('page-changed', page);
并像@page-changed="onPageChanged
一样使用它
【讨论】:
谢谢,我知道这很明显。以上是关于Vue 3 - 从插槽内的子组件发出事件的主要内容,如果未能解决你的问题,请参考以下文章