3. 创建一个菜单组件-DeepSeek辅助编程

在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"
    >
      <TMenuItem
        v-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.index
    if (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"
    >
      <div
        class="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-item
          v-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) return
    
    if (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给我们写的这个组件了
0
posted @ 2025-03-14 15:23  Terry841119  阅读(46)  评论(0)    收藏  举报