? ? ? ? 在上一篇文章中,以Vue2的選項(xiàng)式 API風(fēng)格,封裝了遞歸型菜單組件,但是這其中存在著一些問(wèn)題,例如:
????????【1】子組件menuList.vue中,通過(guò)this.$emit()方式定義的事件,在Vue3組合式API風(fēng)格父組件中可能會(huì)被執(zhí)行多次。之所以說(shuō)是可能,是因?yàn)槲疫@測(cè)試中確實(shí)遇到了這個(gè)問(wèn)題,子組件中確實(shí)只執(zhí)行了一次,父組件中卻執(zhí)行了兩次。
????????【2】父子組件之間的props傳值風(fēng)格不同,vue3中,我們通常是通過(guò)defineProps API明確定義要傳遞的props屬性,而Vue2中選項(xiàng)式API風(fēng)格的組件,則直接可以通過(guò)export default導(dǎo)出的配置參數(shù)進(jìn)行聲明。這種不一致的寫(xiě)法在我寫(xiě)個(gè)人項(xiàng)目中,一向是不太贊同的。
? ? ? ? ?基于以上原因,我將上一篇文章《Vue:Elemenu-Plus遞歸型菜單組件封裝》中的組件進(jìn)行了改寫(xiě),改為Vue3組合式API風(fēng)格的組件,并對(duì)上述問(wèn)題進(jìn)行了解決。
? ? ? ? 示例代碼如下,文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-549779.html
菜單子組件定義
? ? ? ? 示例代碼如下,
<!-- 多級(jí)菜單組件抽取 -->
<template>
<el-menu :default-active="props.activeIndex" :class="props.customMenuClass" background-color="transparent"
text-color="#fff" active-text-color="#ffef40" :mode="props.mode" @select="onSelect" :ellipsis="false">
<template v-for="(item) in props.items">
<template v-if="item.children">
<el-sub-menu :index="item.index" popper-class="el-sub-menu-popper-class">
<template #title>
<router-link :to="item.path">
<el-icon>
<component :is="item.meta.icon" :size="24"></component>
</el-icon>
<span>{{ item.meta.title }}</span>
</router-link>
</template>
<!-- 直接使用文件名即可,不用考慮name的問(wèn)題 -->
<!-- <menu-list :items="item.children" :mode="item.meta.mode" @select="onSelect"></menu-list> -->
<index :items="item.children" :mode="item.meta.mode" @select="onSelect"></index>
</el-sub-menu>
</template>
<template v-else>
<el-menu-item :index="item.index" :key="item.path">
<router-link :to="item.path">
<el-icon>
<component :is="item.meta.icon" :size="24"></component>
</el-icon>
<span>{{ item.meta.title }}</span>
</router-link>
</el-menu-item>
</template>
</template>
</el-menu>
</template>
<script setup>
import { toRef, watch } from 'vue'
//declare props from parent-component
const props = defineProps({
customMenuClass: {
type: String,
required: false,
default: "el-menu-class",
},
mode: {
type: String,
default: "horizontal",
},
items: {
type: Array,
required: true,
},
activeIndex: {
type: String,
required: false,
default: "",
}
})
//declare emtits by current-component
const emits = defineEmits(["select"])
//declare watch-calls
watch(() => props.activeIndex, (value, oldValue) => {
console.log('新的activeIndex,', value)
})
//declare methods
const onSelect = (key, keyPath, item) => {
emits("select", { value: true, key, keyPath, item })
}
</script>
<style lang="scss" scoped>
.el-menu-class {
.el-menu-item:not(.is-disabled):hover {
background-color: rgba(127, 255, 212, .3);
}
}
</style>
<style lang="scss">
.el-sub-menu-popper-class {
background-color: $base-background-color !important;
}
</style>
父組件調(diào)用
<menu-list :items="menuList" :active-index="activeIndex" mode="horizontal" @select="clickHandler" />
//其中,clickHandler為emit方式定義的子組件事件,函數(shù)定義如下
const clickHandler = ({ value, key, keyPath, item }) => {
console.log('clickHandler', value, key, keyPath)
console.log("item-value", item)
}
? ? ? ? 在此之上,我們還可以完成一些其他操作,例如:菜單路由切換的本地緩存,以保證每次進(jìn)入項(xiàng)目主頁(yè)時(shí),路由會(huì)自動(dòng)跳轉(zhuǎn)到上一次操作的頁(yè)面;結(jié)合后端API接口調(diào)用,實(shí)現(xiàn)真正意義上的動(dòng)態(tài)菜單;通過(guò)自定義指令,實(shí)現(xiàn)前端頁(yè)面操作的權(quán)限控制等等。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-549779.html
到了這里,關(guān)于Vue3:Elemenu-Plus遞歸型菜單組件封裝(2)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!