Vue组件插槽能否用v-bind?Vuetify菜单绑定报错求解决方案
解决Vuetify菜单组件插槽绑定activator的TypeError问题
先说说问题出在哪:
- 父组件里直接写
this.$refs.miniProfile(uuid)是错误的,要调用组件暴露的open方法才对 - 把activator直接绑定到
<slot>标签上不可行,slot不是真实DOM元素,得把activator包含的事件和属性传递给插槽内的具体元素使用
下面是修正后的完整可运行代码:
可复用迷你资料菜单组件(MiniProfileMenu.vue)
<template> <v-menu v-model="menu" :close-on-content-click="false" location="end" > <template v-slot:activator="{ on, attrs }"> <!-- 将菜单激活所需的事件、属性传递给插槽,由内部元素绑定 --> <slot v-bind="{ on, attrs }" /> </template> <v-card class="profile-card"> <v-row align="center"> <v-col cols="auto" style="width: 64px"> <!-- 通过props接收用户头像,支持动态渲染 --> <v-img :src="user?.avatar" alt="用户头像" width="64" height="64" rounded /> </v-col> <v-col> <h4 class="mb-1">{{ user?.name || '匿名用户' }}</h4> <p class="text-grey-darken-1 text-sm">{{ user?.desc || '暂无个人描述' }}</p> </v-col> </v-row> <!-- 可添加菜单操作选项 --> <v-divider class="my-2"></v-divider> <v-list dense> <v-list-item @click="close"> <v-list-item-icon> <v-icon>mdi-logout</v-icon> </v-list-item-icon> <v-list-item-title>退出登录</v-list-item-title> </v-list-item> </v-list> </v-card> </v-menu> </template> <script> export default { name: "MiniProfileMenu", // 接收用户信息,让组件支持动态渲染不同用户数据 props: { user: { type: Object, default: () => ({}) } }, data() { return { menu: false }; }, methods: { open() { this.menu = true; }, close() { this.menu = false; } } }; </script> <style scoped> .profile-card { width: 100%; min-width: 280px; } </style>
页面调用示例(DashboardCommunityPage.vue)
<template> <v-container> <v-row> <v-spacer /> <v-col cols="auto"> <mini-profile-menu ref="miniProfile" :user="currentUser" > <!-- 将插槽传递的on事件、attrs属性绑定到div上,菜单会关联该元素 --> <div v-on="on" v-bind="attrs" class="pa-2 cursor-pointer"> 点击打开我的资料 </div> </mini-profile-menu> </v-col> <v-spacer /> </v-row> </v-container> </template> <script> import MiniProfileMenu from "#/components/MiniProfileMenu.vue"; export default { name: "DashboardCommunityPage", components: { MiniProfileMenu }, data() { return { // 示例用户数据,实际可从接口获取 currentUser: { name: "张三", desc: "前端开发工程师", avatar: "https://via.placeholder.com/64" }, user_uuid: "123456" }; }, methods: { // 如需手动触发菜单打开,调用此方法即可 openMiniProfile() { this.$refs.miniProfile.open(); } } }; </script>
核心修改说明
- 拆分activator属性:把v-menu的activator拆分为
on(事件集合)和attrs(HTML属性)传递给插槽,让内部div元素绑定这些内容,确保菜单能正确关联到点击的DOM元素,避免null引用错误 - 组件Props化:通过
userprops接收用户数据,使组件可以在不同页面传递不同用户信息,提升复用性 - 修正方法调用:原代码直接调用ref对象的方式错误,改为调用组件的
open方法;同时绑定on事件后,点击div会自动触发菜单打开 - 移除冗余变量:删除原组件中无用的
activator变量,简化代码逻辑
修改完成后,点击div元素时菜单会精准显示在元素旁,不会再出现TypeError: Cannot read properties of null (reading 'key')错误,组件也能在各页面灵活复用。
内容的提问来源于stack exchange,提问作者Poisonous Purple
相关产品推荐
相关产品推荐

