前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >BuildAdmin12:vue3中子组件调用父组件方法,实现弹出框

BuildAdmin12:vue3中子组件调用父组件方法,实现弹出框

原创
作者头像
叫我阿柒啊
修改2024-06-11 17:13:27
3190
修改2024-06-11 17:13:27
举报
文章被收录于专栏:vue前端之路入门到放弃之路

前言

上一篇写了弹出框出现位置定位,以及标签禁用的实现。本篇文章就开始写五个标签功能的实现,本篇文章针对重新加载标签,展开功能实现的过程。

弹出框定义点击事件

在弹出框中,定义了click事件,绑定了onContextmenuItem方法。

代码语言:html
复制
<li class="el-dropdown-menu__item" :class="item.disabled ? 'is-disabled' : ''" tabindex="-1" 
    @click="onContextmenuItem(item)">
    <Icon size="12" :name="item.icon" />
    <span>{{ item.label }}</span>
</li>

我们看看onContextmenuItem是如何定义的。

代码语言:JavaScript
复制
const emits = defineEmits<{
    (e: 'contextmenuItemClick', item: ContextmenuItemClickEmitArg): void
}>()

// 点击标签,将contextItem emit给父组件
const onContextmenuItem = (item: ContextmenuItemClickEmitArg) => {
    if (item.disabled) return
    item.menu = toRaw(state.menu)
    emits('contextmenuItemClick', item)
}

onContextmenuItem将item的menu赋值(标签禁用的不赋值,直接return返回,同时调用父组件的contextmenuItemClick方法。*

在vue中,defineProps是子组件接收父组件传递的值,defineEmits则子组件调用父组件事件,同时还可以传递参数,总的来说都是父子组件通信的。

这里的item指的就是之前讲的contextmenuItems中的功能标签。

代码语言:javascript
复制
contextmenuItems: [
    {name: 'refresh', label: '重新加载', icon: 'fa fa-refresh'},
    {name: 'close', label: '关闭标签', icon: 'fa fa-times'},
    {name: 'fullScreen', label: '当前标签全屏', icon: 'el-icon-FullScreen'},
    {name: 'closeOther', label: '关闭其他标签', icon: 'fa fa-minus'},
    {name: 'closeAll', label: '关闭全部标签', icon: 'fa fa-stop'},
]

弹出框组件调用了父组件tabs的contextmenuItemClick方法,并传递了item作为参数。

ContextmenuItemClickEmitArg

其中,形参中的ContextmenuItemClickEmitArg类型是自定义的接口。

代码语言:JavaScript
复制
export interface ContextMenuItem {
    name: string
    label: string
    icon?: string
    disabled?: boolean
}

export interface ContextmenuItemClickEmitArg extends ContextMenuItem {
    menu?: RouteLocationNormalized
}

相当于在contextmenuItems类型上,添加了一个menu字段。menu字段在BuildAdmin中指的是菜单路由,这个munu是如何赋值的呢?

在上一篇讲到弹出框弹出时,右键tab标签,调用弹出框组件的onShowContextmenu方法显示弹出框时,onShowContextmenu就绑定了tab的路由,将menu赋值给了state.menu,在弹出框的标签点击事件onContextmenuItem就将state.menu赋值给了item.menu。

赋值在代码的61和82行。

tabs定义标签事件

在tabs中使用弹出框组件时,通过v-on来定义contextmenuItemClick方法,这样弹出框组件才能接收。

代码语言:html
复制
<Contextmenu ref="contextmenuRef" :items="state.contextmenuItems" @contextmenuItemClick="onContextmenuItem"/>

contextmenuItemClick又指向了onContextmenuItem方法,contextmenuItemClick就是实现标签功能具体的方法。

代码语言:JavaScript
复制
const onContextmenuItem = async (item: ContextmenuItemClickEmitArg) => {
    const {name, menu} = item
    if (!menu) return
    switch (name) {
        case 'refresh':
            proxy.eventBus.emit('onTabViewRefresh', menu)
            break
        case 'close':
            closeTab(menu)
            break
        case 'closeOther':
            closeOtherTab(menu)
            break
        case 'closeAll':
            closeAllTab(menu)
            break
        case 'fullScreen':
            if (route.path !== menu?.path) {
                router.push(menu?.path as string)
            }
            navTabs.setFullScreen(true)
            break
    }
}

在onContextmenuItem中,就是对ContextmenuItemClickEmitArg类型的item做了一个switch case的判断。

if (!menu) return是对禁用的标签不作处理,因为在上图onContextmenuItem方法的第81行,如果标签禁用,则menu不赋值。

思考

为什么非要在tabs中实现实现这些功能,还要父子组件各种值和方法传递,直接在弹出框组件实现不好吗?

  1. 灵活性:如果有多个组件使用弹出框组件,父组件通过传递不同的item,就能定制每个组件的弹出框标签列表。
  2. tabs中已经拿到了一些变量,例如所有的tab(tabsViews),激活的tab等。就拿关闭其他标签来说,你得知道打开了哪些标签,才能关闭。这些在tabs实现的时候都定义了,所以在tabs中实现这些功能比较方便,直接可以复用。

结语

本篇主要根据vue3中父子组件方法调用通信,讲了BuildAdmin的弹出框标签功能架构的实现,主要是对emit的一个理解和使用.下一篇文章写重新加载标签功能的具体实现.

我正在参与2024腾讯技术创作特训营第五期有奖征文,快来和我瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 弹出框定义点击事件
  • ContextmenuItemClickEmitArg
  • tabs定义标签事件
  • 思考
  • 结语
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档