在deepseek中输入:
创建一个vue组件 组件实现菜单的功能 需要让调用该组件是可以自定义一些属性:mode:horizontal横向显示/vertical纵向显示,background-color,text-color,active-text-color,model:通过该model绑定菜单/model为MenuItem的数组 MenuItem由这些参数构成:index:唯一标识/控制显示先后顺序,title:标题/显示的菜单标题,disabled:是否禁用,to:url跳转地址,subitem:子菜单model 支持多级菜单 支持菜单图标
deepseek返回的代码:
Menu的代码
<!-- TMenu.vue --> <template><div class="menu-container":class="[modeClass]":style="containerStyle"><TMenuItemv-for="item in processedMenu":key="item.index":item="item":current-active="activeIndex":depth="0"@item-click="handleItemClick"/></div></template><script setup>import { ref, computed, provide, defineProps, defineEmits } from 'vue'import TMenuItem from './TMenuItem.vue'const props = defineProps({model: {type: Array,required: true},mode: {type: String,default: 'horizontal',validator: v => ['horizontal', 'vertical'].includes(v)},backgroundColor: {type: String,default: '#ffffff'},textColor: {type: String,default: '#303133'},activeTextColor: {type: String,default: '#409eff'}})const emit = defineEmits(['update:modelValue'])// 提供样式变量给子组件provide('menuColors', {backgroundColor: computed(() => props.backgroundColor),textColor: computed(() => props.textColor),activeTextColor: computed(() => props.activeTextColor)})const activeIndex = ref('')const modeClass = computed(() => `menu-${props.mode}`)const containerStyle = computed(() => ({backgroundColor: props.backgroundColor}))// 处理菜单数据const processedMenu = computed(() => {return props.model.map(item => ({ ...item })).sort((a, b) => (a.order || 0) - (b.order || 0))})const handleItemClick = (item) => {activeIndex.value = item.indexif (item.to) {// 这里可以集成路由跳转逻辑console.log('Navigate to:', item.to)}emit('item-click', item)}</script><style scoped>.menu-container {display: flex;transition: all 0.3s;}.menu-horizontal {flex-direction: row;}.menu-vertical {flex-direction: column;}</style>
MenuItem的代码
<!-- TMenuItem.vue --> <template><div class="menu-item":class="[`depth-${depth}`,{ 'is-active': isActive },{ 'is-disabled': item.disabled }]" :style="itemStyle"><divclass="menu-item-content"@click="handleClick"><span class="menu-item-title">{{ item.title }}</span><span v-if="hasSubmenu"class="menu-arrow":class="[isSubmenuOpen ? 'arrow-open' : '']">▾</span></div><div v-if="hasSubmenu && isSubmenuOpen"class="submenu":class="[submenuClass]"><t-menu-itemv-for="subItem in sortedSubmenu":key="subItem.index":item="subItem":current-active="currentActive":depth="depth + 1"@item-click="$emit('item-click', $event)"/></div></div></template><script setup>import { computed, inject, ref } from 'vue'const props = defineProps({item: {type: Object,required: true},currentActive: String,depth: {type: Number,default: 0}})const emit = defineEmits(['item-click'])const menuColors = inject('menuColors')const isSubmenuOpen = ref(false)const hasSubmenu = computed(() => props.item.submenu?.length > 0)const sortedSubmenu = computed(() => props.item.submenu?.sort((a, b) => (a.order || 0) - (b.order || 0)) || []) || []const isActive = computed(() => props.currentActive === props.item.index)const itemStyle = computed(() => ({color: isActive.value ? menuColors.activeTextColor : menuColors.textColor}))const submenuClass = computed(() => props.depth === 0 ? 'submenu-root' : '')const handleClick = () => {if (props.item.disabled) returnif (hasSubmenu.value) {isSubmenuOpen.value = !isSubmenuOpen.value} else {emit('item-click', props.item)}}</script><style scoped>.menu-item {position: relative;cursor: pointer;transition: all 0.3s;}.menu-item.depth-0 {padding: 12px 20px;}.menu-item.depth-1 {padding: 8px 30px;}.menu-item.depth-2 {padding: 8px 40px;}.menu-item-content {display: flex;align-items: center;gap: 8px;}.menu-item-title {white-space: nowrap;}.menu-arrow {transition: transform 0.3s;margin-left: auto;}.arrow-open {transform: rotate(180deg);}.submenu {position: absolute;background-color: v-bind('menuColors.backgroundColor');min-width: 160px;box-shadow: 0 2px 12px rgba(0,0,0,0.1);}.menu-vertical .submenu-root {left: 100%;top: 0;}.menu-horizontal .submenu-root {top: 100%;left: 0;}.menu-item.is-disabled {opacity: 0.6;cursor: not-allowed;}.menu-item:hover:not(.is-disabled) {background-color: rgba(0,0,0,0.04);}</style>
调用的代码
<template><TMenu:model="menuData"mode="vertical"background-color="#f5f7fa"text-color="#606266"active-text-color="#409eff"@item-click="handleMenuClick"/> </template><script setup> import { ref } from 'vue' import TMenu from './components/TMenu.vue'const menuData = ref([{index: '1',title: '首页',order: 1,to: '/home'},{index: '2',title: '产品中心',order: 2,submenu: [{index: '2-1',title: '手机',submenu: [{ index: '2-1-1', title: '旗舰机型' },{ index: '2-1-2', title: '性价比机型' }]},{index: '2-2',title: '电脑',disabled: true}]},{index: '3',title: '联系我们',order: 3,submenu: [{ index: '3-1', title: '在线客服' },{ index: '3-2', title: '电话联系' }]} ])const handleMenuClick = (item) => {console.log('Clicked menu:', item) } </script>
然后运行,我们就可以看到deepseek给我们写的这个组件了
