vue3通过el-cascader实现动态菜单切换页面

如果只有一级菜单只会显示一个按钮
在这里插入图片描述

 <div style="width: 100%; margin-top: 10px; display: flex; align-items: center; border-bottom: 1px solid #ccc;">
    <template v-for="(menu, index) in cascaderData" :key="index">
      <el-cascader
          v-if="menu.children && menu.children.length > 0"
          style="width: 120px;"
          v-model="selectedOptions[index]"
          :options="menu.children"
          @change="handleCascaderChange(index, $event)"
          :placeholder="menu.label"
      >
      </el-cascader>

      <el-button :style="{color: buttonColor}" plain @click="handleSelect(String(index))" v-else>
        {{ menu.label }}
      </el-button>
    </template>
  </div>

菜单结构说明:component对应的就是你要跳转的页面组件,也就是上面import进来的组件。然后通过emitComponentChange方法来跳转对应页面。

<script setup>
import {useRouter} from 'vue-router';
import signal from '@/views/drawing/station/index';
import permutation from '@/views/drawing/permutationtable/permutation';
import gdgtable from '@/views/drawing/permutationtable/gdgtable';
import request from "../../../utils/request";
import {watch} from "vue";

import {useStationsStore} from "@/views/drawing/store/index";

const stationsStore = useStationsStore();

const router = useRouter();

const buttonColor = ref('black')

const drawCodeList = ref([]);

const xhjMenu = ref([])

const cascaderData =ref( [
  {
    value: '0',
    label: '基础数据',
    children: [],
    component: signal
  },
  {
    value: '1',
    label: '封面及目录',
    children: [
      {value: '1-1', label: '封面'},
      {value: '1-2', label: '目录'},
    ]
  },
  {
    value: '2',
    label: '测试1',
    children: [
      {value: '2-1', label: '测试1-1'},
      {value: '2-2', label: '测试1-2'},
    ]
  },
  {
    value: '4',
    label: '测试3',
    children: [
      {value: '4-1', label: '测试3-1', component: lsbtable},
      {value: '4-2', label: '测试3-2', component: dclsbtable},
    ]
  },
  {
    value: '6',
    label: '测试4',
    children: [
      {value: '6-1', label: '测试4-1', children: xhjMenu.value},	//这里用到了动态请求后端获取的三级菜单
      {value: '6-2', label: '测试4-2', component: dctable},
      {value: '6-3', label: '测试4-3'},
      {
        value: '6-4', label: '测试4-4', children: [
          {value: '6-4-1', label: '测试4-4-1', component: qdcjtable},
          {value: '6-4-2', label: '测试4-4-2'},
        ]
      },
      {value: '6-5', label: '测试4-5'},
    ]
  },
]);

// 用于存储选择的菜单项
const selectedOptions = ref([]);

// 处理 el-cascader 改变事件
const handleCascaderChange = (index, value) => {
  recoverButton(index);
  let menu = String(value)
  if (value.length === 2) {			//如果是二级菜单,截取第二位数据
    menu = String(value[1])
  }
  handleSelect(menu)
}

//处理菜单跳转事件
const handleSelect = async (menu) => {
  buttonColor.value = '#a7aab1'
  let component = findComponentByValue(cascaderData.value, menu);
  if (menu === '0') {
    buttonColor.value = 'black';
    recoverButton(menu);
  }
  if (menu === '7-3') {
    const type = await changeStation();
    if (type === 4) {
      emitComponentChange(jkgksktable);
    } else {
      emitComponentChange(jkgTktable);
    }
  }
  if (menu.includes('xhjtable')){
    let tuzhiCode = findTuZhiCodeByValue(cascaderData.value, menu);
    stationsStore.setTuzhiCode(tuzhiCode);
    emitComponentChange(component);
  }
  if (component != null) {
    emitComponentChange(component);
  }
};

//这个方法是用来跳转对应页面的
const emitComponentChange = (component) => {
  // 触发自定义事件,传递组件或其他数据
  const event = new CustomEvent('componentChange', {detail: component});
  window.dispatchEvent(event);
};

//将其他按钮恢复原状
function recoverButton(index) {
  console.log(selectedOptions.value)
  for (const item of cascaderData.value) {
    selectedOptions.value[item.value] = []; //全部恢复原状
    // if (parseInt(item.value) !== index) {
    //   selectedOptions.value[item.value] = [];//将除了当前选中的菜单框都恢复原状
    // }
  }
  console.log(selectedOptions.value)
}

// 匹配菜单页面
function findComponentByValue(data, targetValue) {
  for (let i = 0; i < data.length; i++) {
    const item = data[i];
    if (item.value === targetValue) {
      return item.component;
    }
    if (item.children && item.children.length > 0) {
      const result = findComponentByValue(item.children, targetValue);
      if (result) {
        return result;
      }
    }
  }
  return null;
}

// 获取图纸code
function findTuZhiCodeByValue(data, targetValue) {
  for (let i = 0; i < data.length; i++) {
    const item = data[i];
    if (item.value === targetValue) {
      return item.tuzhiCode;
    }
    if (item.children && item.children.length > 0) {
      const result = findTuZhiCodeByValue(item.children, targetValue);
      if (result) {
        return result;
      }
    }
  }
  return null;
}

listDingXingTuList().then((data) => { 	//这里通过请求后端接口动态获取三级菜单并赋值
  drawCodeList.value = data.data;
  cascaderData.value[6].children[0].children = drawCodeList.value.map(item => ({
    value: 'xhjtable'+item.id,		
    label: item.tuzhiName,
    component: xhjtable,
    tuzhiCode: item.tuzhiCode		//格式和一二级菜单保持一致,可以增加字段
  }));
})

</script>

下面是切换页面后要显示的目标页面,这里接收上面emitComponentChange 方法传递过来的组件

<template>
  <el-row>
    <el-col :span="20">
    
      <!-- 顶部菜单 -->
      <div v-if="showTop">
        <topmenu />
      </div>
      
      <!-- 右侧下方区域动态切换的内容 -->
      <div style="flex: 1;">
        <component :is="currentComponent" />
      </div>
      
    </el-col>
  </el-row>
</template>

<script setup>
import {onMounted, shallowRef} from 'vue';
import Topmenu from "./station/topmenu";

const currentComponent = shallowRef(signal);

//主动监听事件
onMounted(() => {
  window.addEventListener('componentChange', (event) => {
    const component = event.detail;
    // 在这里处理接收到的组件或其他数据
    currentComponent.value = component;
  });
});

getStationList()
</script>

还有一种方式是通过el-menu实现的,效果同上,使用的js方法都是一样的

<el-menu
      :default-active="activeIndex"
      class="el-menu-demo"
      mode="horizontal"
      @select="handleSelect"
      background-color="#f8f8f9"
      style="margin-top: 20px;margin-left: 1px"
  >
    <template v-for="(item, index) in cascaderData">
      <template v-if="!item.children">
        <el-menu-item :key="item.index" :index="item.value">
          {{ item.label }}
        </el-menu-item>
      </template>
      <el-sub-menu v-else :key="item.value" :index="item.value">
        <template #title>{{ item.label }}</template>
        <template v-for="(child, childIndex) in item.children">
          <template v-if="!child.children">
            <el-menu-item :key="child.value" :index="child.value">
              {{ child.label }}
            </el-menu-item>
          </template>
          <el-sub-menu v-else :key="child.value + '-sub'" :index="child.value">
            <template #title>{{ child.label }}</template>
            <el-menu-item
                v-for="(subItem, subIndex) in child.children"
                :key="subItem.value"
                :index="subItem.value"
            >
              {{ subItem.label }}
            </el-menu-item>
          </el-sub-menu>
        </template>
      </el-sub-menu>
    </template>
  </el-menu>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/474562.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Source Insight关于复制一段代码会自动添加空格或者Tab键的配置取消

Source Insight关于复制一段代码会自动添加空格或者Tab键的配置取消&#xff0c;这个情况在我们复制代码的时候对格式非常不友好&#xff0c;解决办法如下。 如下&#xff0c;我们可以设置相关配置&#xff1a; 设置完成后&#xff0c;然后再去复制&#xff0c;可以看到就没有相…

基于C/C++的easyx实现贪吃蛇游戏

文章目录&#xff1a; 一&#xff1a;运行效果 1.演示 2.思路和功能 二&#xff1a;代码 文件架构 Demo 必备知识&#xff1a;基于C/C的easyx图形库教程 一&#xff1a;运行效果 1.演示 效果图◕‿◕✌✌✌ 基于C/C的easyx实现贪吃蛇游戏运行演示 参考&#xff1a;【C语…

一文带你速通go语言指针

写在文章开头 关于go语言的系列文章更新了有一段时间了&#xff0c;从阅读量来看大部分接触go语言的读者都是Java开发&#xff0c;因为Java这门语言没有指针的概念&#xff0c;所以笔者专门整理了一篇文章带读者快速了解一下指针的概念。 Hi&#xff0c;我是 sharkChili &…

【蓝桥杯嵌入式】四、各种外设驱动(十)USART+DMA通信方式和串口通信协议的设计与使用

温馨提示&#xff1a;本文不会重复之前提到的内容&#xff0c;如需查看&#xff0c;请参考附录 【蓝桥杯嵌入式】附录 目录 重点提炼&#xff1a; 一、需求分析 1、需要的外设资源分析&#xff1a; 2、外设具体分析&#xff1a; CubeMX配置中&#xff0c;我们需要改动的参…

C 语言中位取反操作符 ~ 和逻辑取反操作符 !

在 C 语言中&#xff0c;有两种取反操作符&#xff0c;分别是位取反操作符 ~ 和逻辑取反操作符 !。 位取反操作符 ~&#xff1a; 位取反操作符 ~ 是一个一元操作符&#xff0c;用于执行按位取反操作。它会将操作数的每个位取反&#xff0c;即将 0 变为 1&#xff0c;将 1 变为 …

成为高效Java工程师的干货笔记

&#x1f482; 个人网站:【 摸鱼游戏】【神级代码资源网站】【工具大全】&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交流&#xff0c;摸鱼划水的小伙伴&#xff0c;请点击【全栈技术交流群】 作为一名Java工程师&…

手撕算法-判断是不是平衡二叉树

描述&#xff1a;分析&#xff1a;只需要看左右子树的深度差小于等于1&#xff0c;且左右子树都是平衡二叉树。 代码&#xff1a; public class Solution {public boolean IsBalanced_Solution (TreeNode pRoot) {if (pRoot null) return true;return Math.abs(deep(pRoot.l…

科普一下|了解胎牛血清

胎牛血清是从未出生的胎牛中经过穿刺采血后&#xff0c;经过层析、离心、三级0.1m微滤除菌等操作而收集到的上清液。本文将会探讨胎牛血清的生产流程、应用、储存以及胎牛血清的成分&#xff0c;让我们一起走进胎牛血清的世界吧&#xff01; 1、胎牛血清的生产流程&#xff1a…

redis的安装与string类型

1. redis的安装 1.1 升级gcc版本 因为centos7.x的gcc版本还是4.8.5&#xff0c;而编译指定的版本是需要5.3以上。 环境部署与安装scl源 yum install gcc cmake -y --部署安装环境 yum install centos-release-scl scl-utils-build -y --安装scl源 安装gcc新版本 yum -y ins…

Batch Normalization(批量归一化)和 Layer Normalization(层归一化)

Batch Normalization(批量归一化)和 Layer Normalization(层归一化)都是深度学习中用于改善网络训练过程的归一化技术。尽管它们的目标相似,即通过规范化中间层的激活值来加速训练过程并提高性能,但它们在细节上有所不同。 Batch Normalization (批量归一化) Batch Nor…

如何处理WordPress网站域名循环重定向

我在 HostEase 搭建了一个 WordPress 网站。在访问网站时出现了循环重定向的问题。经检查&#xff0c;发现是我在 .htaccess 文件中设置的重定向规则导致的。 重定向循环通常指的是一个网页或者URL地址在不断地进行重定向&#xff0c;最终形成一个循环&#xff0c;导致网页无法…

docker swarm 集群创建

1&#xff0c;目的&#xff1a; 通过docker swarm 工具将一台或者多台安装了docker的服务器组成一个完整的集群&#xff0c;该集群中的node节点可以通过Leader节点管理。在使用docker stack部署时&#xff0c;可以将容器自动分发到合适的节点上。 2&#xff0c;服务器准备&am…

C# 数组(Array)

C# 数组&#xff08;Array&#xff09; 初始化数组 声明一个数组不会在内存中初始化数组。当初始化数组变量时&#xff0c;您可以赋值给数组。 数组是一个引用类型&#xff0c;所以您需要使用 new 关键字来创建数组的实例。 例如&#xff1a; double[] b new double[10];…

VMware 替代专题 | 浅析 VMware 与 SmartX 超融合 I/O 路径差异及其影响

不同的超融合软件&#xff0c;其读写机制有一定的差异性&#xff0c;I/O 路径也不尽相同&#xff0c;这使得他们在 I/O 读写效率以及资源占用上都有不同的表现。有兴趣着手构建超融合基础架构的用户&#xff0c;可能会希望了解更多关于 I/O 路径的细节&#xff0c;从而在实施之…

二极管使用总结

1、整流的二极管、快恢复二极管、肖特基二极管做整流的差异。 标准整流二极管与快恢复二极管主要差异在恢复时间上。 • Standard rectifiers with a trr > 500 ns • Fast rectifiers with a 100 ns < trr < 500 ns • Ultrafast rectifiers with a trr < 100…

软件工程导论画图题汇总:期末+复试

文章目录 一、数据模型&#xff1a;实体联系图&#xff08;E-R图&#xff09;二、行为模型&#xff1a;状态转换图三、功能模型&#xff1a;数据流图四、数据字典五、系统流程图六、层次图七、HIPO图八、结构图九、程序流程图十、盒图十一、PAD图十二、判定表、判定树 一、数据…

【链表】Leetcode 19. 删除链表的倒数第 N 个结点【中等】

删除链表的倒数第 N 个结点 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], n 2 输出&#xff1a;[1,2,3,5] 解题思路 1、使用快慢指针找到要删除节点的前一个节点。2、删…

30-如何使用命令给共享文件夹给人员授权?windows 的共享文件

&#xff08;1&#xff09;需求&#xff1a; 维护公司的DFS真的很烦&#xff0c;每天要给他们人员进行授权。用AD组可以&#xff0c;但是呢&#xff0c;用户想看到他们授权情况&#xff0c;没办法只能一个个授权吗&#xff1f;可以使用命令吗&#xff1f;可以的 &#xff08;2&…

【SpringMVC】知识汇总

SpringMVC 短暂回来&#xff0c;有时间就会更新博客 文章目录 SpringMVC前言一、第一章 SpingMVC概述二、SpringMVC常用注解1. Controller注解2. RequestMapping注解3. ResponseBody注解4. RequestParam5. EnableWebMvc注解介绍6. RequestBody注解介绍7. RequestBody与RequestP…

腾讯游戏全年收入1799亿,DNF手游有望突破100亿

易采游戏网3月21日消息&#xff1a;腾讯公司近期发布的2023财务年度报告显示&#xff0c;其营收和净利润双双显著上升&#xff0c;尤以游戏业务成绩不俗。管理团队承诺&#xff0c;将继续深耕既有游戏产品&#xff0c;同时强化新游研发力度&#xff0c;提升市场竞争力。引人瞩目…