vue组件开发:构建响应式快捷导航

使用Vue来完成项目中的首页导航+左侧菜单 页面上使用的面包屑,查询条件,表格,分页等空间,可以查看element-ui官网。该步骤主要关注页面布局,并没有绑定数据,编写完成后,观察页面效果。 BookList.vue: 阅读详情

前言

快捷导航不仅能够显著提升系统的灵活性和用户交互性,还极大地增强了用户的操作体验。本文将展示如何在 vue 中实现一个既可自定义又具备响应式特性的快捷导航菜单。


一、实现思路

列表页

  • 结构设计

    定义页面结构,包含一个导航卡片和一个对话框组件;
    导航卡片中包含一个标题、添加按钮和导航项列表;
    使用 v-for 指令遍历 routeData 数组,动态生成每个导航项。

  • 数据管理

    在 data 中定义 routeData 数组,存储导航项的信息(如图标和标题);
    定义 dialogChild 变量,用于控制对话框的显隐状态。

  • 事件处理

    handleCellClick(item):处理点击导航项的事件,输出所点击的项的信息;
    deleteItem(index):处理删除导航项的事件,通过 splice 方法从 routeData 中移除指定项;
    navigationAdd():打开添加导航项的对话框,将 dialogChild 设置为 true。

1.1 列表组件

<template>
  <div class="navigation">
    <div class="cardContent">
      <el-card class="box-card">
        <div slot="header">
          <span />
          <span class="cardName">快捷导航</span>
          <el-link style="float: right" type="primary" @click="navigationAdd">添加</el-link>
        </div>
        <div v-if="routeData && routeData.length" class="gridContainer">
          <!-- 遍历路由数据,生成每个导航项 -->
          <div v-for="(item, index) in routeData" :key="index" class="gridContent">
            <div class="content" :title="item.title" @click.stop="handleCellClick(item)">
              <p><img :src="item.imgUrl" alt="" /></p>
              <p>{{ item.title }}</p>
            </div>
            <div class="overlay">
              <i title="删除" class="el-icon-circle-close" @click.stop="deleteItem(index)"></i>
            </div>
          </div>
        </div>
        <div v-else><el-empty description="暂无数据"></el-empty></div>
      </el-card>
    </div>
    <navigation-dialog :dialogChild.sync="dialogChild" />
  </div>
</template>

<script>
import NavigationDialog from "./navigationDialog.vue";
export default {
  components: { NavigationDialog },
  data() {
    return {
      dialogChild: false, // 控制对话框显隐状态
      routeData: [
        //模拟数据
        {
          imgUrl: require("../assets/demo.png"),
          title: "数据统计",
        },
        {
          imgUrl: require("../assets/demo.png"),
          title: "订单管理",
        },
        {
          imgUrl: require("../assets/demo.png"),
          title: "汇总信息",
        },
        {
          imgUrl: require("../assets/demo.png"),
          title: "客服管理",
        },
        {
          imgUrl: require("../assets/demo.png"),
          title: "财物中心",
        },
        {
          imgUrl: require("../assets/demo.png"),
          title: "系统管理",
        },
        {
          imgUrl: require("../assets/demo.png"),
          title: "系统监控",
        },
        {
          imgUrl: require("../assets/demo.png"),
          title: "系统工具",
        },
      ],
    };
  },
  methods: {
    // 点击导航项的处理函数
    handleCellClick(item) {
      console.log("item:", item);
    },
    // 删除导航项的处理函数
    deleteItem(index) {
      this.routeData.splice(index, 1);
    },
    // 打开添加导航项对话框的处理函数
    navigationAdd() {
      this.dialogChild = true;
    },
  },
};
</script>

<style lang="less" scoped>
.navigation {
  width: 36%;
  padding: 16px;
  .cardContent {
    span:first-child {
      display: inline-block;
      width: 10px;
      height: 10px;
      background: #409eff;
      margin-right: 10px;
    }
    .cardName,
    .el-link {
      font-weight: bold;
    }
    .gridContainer {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
      gap: 16px;
      padding: 16px;
      .gridContent {
        width: 100px;
        height: 100px;
        border-radius: 4px;
        position: relative;
        box-sizing: border-box;
        overflow: hidden;
        background: linear-gradient(to bottom, rgba(106, 183, 255, 0.7), rgba(106, 183, 255, 0.2));
        display: flex;
        align-items: center;
        justify-content: center;
        text-align: center;
        .content {
          cursor: pointer;
          color: rgb(60, 60, 60);
          img {
            width: 50px;
            height: 50px;
          }
          p:nth-child(2) {
            margin-top: 2px;
            width: 92px;
            padding: 0px 4px;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
          }
        }
      }
      .overlay {
        position: absolute;
        top: 3px;
        right: 3px;
      }
      .el-icon-circle-close {
        cursor: pointer;
        font-size: 18px;
        color: rgb(255, 255, 255);
      }
      .el-icon-circle-close:hover {
        color: rgba(255, 255, 255, 0.5);
      }
    }
  }
}
::v-deep {
  .el-checkbox-button__inner {
    margin: 0 8px 10px 8px;
    border: 1px solid #d3d3d3;
    border-radius: 4px !important;
  }
}
</style>

弹框页

  • 结构设计

    使用 <el-dialog> 组件创建一个对话框,包含标题和内容区域;
    在内容区域中,使用 v-for 遍历 cities 数组,生成每个菜单的选项和复选框。

  • 数据管理

    在 data 中定义 cities 数组,模拟系统管理和监控等菜单项;
    定义 checkStates 对象,用于存储每个菜单的选中状态(全选、部分选中和选中的城市)。

  • 事件处理

    initializeCheckStates():初始化每个菜单的选中状态,设置全选状态和选中的菜单;
    handleCheckAllChange(item):处理全选复选框的变化,更新选中状态;
    handleCheckedCitiesChange(item):处理菜单复选框的变化,更新全选和部分选中状态;
    submit():提交选中的信息,过滤出选中的路由项,并输出到控制台;
    cancel():取消操作,重置选中状态并关闭对话框。

2.1 弹框组件

<template>
  <el-dialog :close-on-click-modal="false" title="添加快捷导航" width="60%" :visible.sync="dialogVisible" @close="cancel">
    <el-card class="box-card">
      <!-- 遍历菜单数组,生成每个菜单的选项 -->
      <div v-for="(item, index) in cities" :key="index" class="checkboxContent">
        <span class="navTit">{{ item.label }}</span>
        <!-- 全选复选框 -->
        <el-checkbox v-model="checkStates[item.label].checkAll" :indeterminate="checkStates[item.label].isIndeterminate" @change="handleCheckAllChange(item)">全选</el-checkbox>
        <!-- 菜单的复选框组 -->
        <el-checkbox-group v-model="checkStates[item.label].checkedCities" size="medium" @change="handleCheckedCitiesChange(item)">
          <el-checkbox-button v-for="(e, isx) in item.router" :key="isx" :label="e.title" border>{{ e.title }}</el-checkbox-button>
        </el-checkbox-group>
      </div>
      <div class="btns">
        <el-button size="medium" type="primary" @click="submit">保 存</el-button>
        <el-button size="medium" @click="cancel">取 消</el-button>
      </div>
    </el-card>
  </el-dialog>
</template>
<script>
export default {
  props: {
    dialogChild: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      dialogVisible: false, // 控制对话框显隐状态
      cities: [
        //模拟数据
        {
          label: "系统管理",
          router: [
            { title: "用户管理", id: 0 },
            { title: "角色管理", id: 1 },
            { title: "菜单管理", id: 2 },
            { title: "部门管理", id: 3 },
            { title: "日志管理", id: 4 },
            { title: "字典管理", id: 5 },
          ],
        },
        {
          label: "系统监控",
          router: [
            { title: "在线用户", id: 6 },
            { title: "定时任务", id: 7 },
          ],
        },
        {
          label: "系统工具",
          router: [{ title: "表单构建", id: 8 }],
        },
      ],
      checkStates: {}, // 存储每个菜单的选中状态
    };
  },
  watch: {
    dialogChild: {
      handler(newName) {
        this.dialogVisible = newName;
      },
      deep: true,
    },
  },
  mounted() {
    this.initializeCheckStates();
  },
  methods: {
    // 初始化每个菜单的选中状态
    initializeCheckStates() {
      this.cities.forEach((item) => {
        this.$set(this.checkStates, item.label, {
          checkAll: false, // 全选状态
          checkedCities: [], // 选中的菜单
          isIndeterminate: false, // 是否为部分选中状态
        });
      });
    },
    // 处理全选复选框的变化
    handleCheckAllChange(item) {
      this.checkStates[item.label].checkedCities = this.checkStates[item.label].checkAll ? item.router.map((e) => e.title) : [];
      this.checkStates[item.label].isIndeterminate = false; // 重置部分选中状态
    },
    // 处理菜单复选框的变化
    handleCheckedCitiesChange(item) {
      const checkedCount = this.checkStates[item.label].checkedCities.length; // 选中的菜单数量
      this.checkStates[item.label].checkAll = checkedCount === item.router.length; // 更新全选状态
      this.checkStates[item.label].isIndeterminate = checkedCount > 0 && checkedCount < item.router.length; // 更新部分选中状态
    },
    // 提交选中的信息
    submit() {
      const selectedInfo = this.cities.map((item) => {
        const { checkedCities } = this.checkStates[item.label]; // 获取当前导航项的选中状态
        const selectedRoutes = item.router.filter((route) => checkedCities.includes(route.title)); // 过滤出选中的路由项
        return {
          label: item.label, // 导航项标签
          selectedRoutes: selectedRoutes.map((route) => ({
            title: route.title,
            id: route.id,
          })), // 选中的路由项
        };
      });
      console.log("选中的信息:", selectedInfo); // 输出选中的信息
    },
    // 取消操作
    cancel() {
      this.initializeCheckStates(); // 重置选中状态
      this.$emit("update:dialogChild", false);
    },
  },
};
</script>

<style lang="less" scoped>
.checkboxContent {
  margin-bottom: 16px;
  .navTit {
    margin-right: 10px;
    color: rgb(41, 107, 255);
    font-weight: bold;
    font-size: 16px;
  }
  .el-checkbox {
    margin: 16px 0;
  }
}
.btns {
  margin-top: 16px;
  display: flex;
  justify-content: right;
}
::v-deep {
  .el-checkbox-button__inner:nth-child(n + 2) {
    margin: 0 !important;
    margin: 0 10px 10px 0 !important;
  }
}
</style>

1.3 组件通信

使用 props 和 $emit 实现父子组件之间的通信。A 页面通过 dialogChild 属性控制 B 页面的对话框显隐状态,并通过 update:dialogChild 事件通知 B 页面关闭对话框。


二、实现效果

在这里插入图片描述

(十)VUE侧边菜单栏导航--基于SpringBoot+MySQL+Vue+ElementUI+Mybatis前后端分离面向小白管理系统搭建 VUE侧边菜单栏导航设计(1)理解并逐步掌握VUE组件的含义;(2)深入理解VUE单页面应用;(3)初步掌握VUE路由的概念和使用方法。 阅读详情

相关推荐

Vue学习之旅:从生命周期到工程化开发与组件实践(生命周期+工程化开发)

我们要实现的小黑记账清单是一个简单的财务管理应用,用户可以在页面上添加账单,查看账单列表,删除账单,并通过饼图直观地展示消费分布情况。下面我们将详细分析每个功能的实现细节。这个小黑记账清单项目展示了 Vue 如何与后端 API 进行交互,并通过 Vue 的响应式数据绑定、生命周期钩子函数和计算属性等特性实现了一个功能完整的应用。我们通过v-for指令实现列表的动态渲染,使用axios进行数据的获取、添加和删除操作,以及利用 Echarts 实现了饼图的动态更新。在开发过程中,要注意v-model。

放下华子我只抽RuiKe5的博客 1375

vue导航栏组件

使用html+css搭建网页导航栏。

qq_45179361的博客 3628

Vue3路由实战:从基础配置到动态路由、导航守卫与组件缓存

在单页面应用(SPA)开发中,路由是实现页面导航与状态管理的核心技术。其原理是通过监听URL变化,动态匹配并渲染对应组件,实现无刷新页面切换。这项技术的核心价值在于提升用户体验与应用性能,支持前进后退、深度链接等原生浏览器行为。在实际工程中,路由管理广泛应用于后台管理系统、电商平台等复杂前端项目,负责处理页面流、权限控制与状态同步。本文聚焦于Vue Router 4在Vue3环境下的实战应用,深入解析动态路由参数传递、导航守卫权限验证等高频场景,并针对Vue3三级嵌套路由缓存页面失效等典型问题,提供结合 `

weixin_30632883的博客 377

vue实现导航栏功能的方法

为此,我们使用如下代码来实现。在该代码中,我们需要先将 button.dialog-position属性设置为 true,然后在后面加上一个 flag. position属性,其作用为使 button.dialog-position属性的值在 DOM中可见,这样可以使用户通过 button.dialog-position属性看到 button.dialog-position属性的值。因此,我们先在初始页面添加一个子组件,如下: 接下来,我们需要给导航栏添加一些内容,以便方便我们查看。

花生日记 7109

Vue.js 导航链接组件详解

它允许我们在单页面应用程序中实现页面导航功能,并通过 Vue Router 来管理路由和组件的加载。其中一个重要的组件是导航链接组件,它用于创建可点击的链接,使用户能够在不同的页面之间进行导航。通过这种方式,我们可以在同一个页面上切换不同的组件,实现单页面应用的导航功能。在实际开发中,我们通常会将导航链接组件嵌套在一个父组件中,以便在整个应用程序中共享导航栏。这个标签是 Vue Router 提供的,用于在单页面应用程序中进行导航。在上面的代码中,我们首先导入了 Vue Router,并在模板中使用了。

HackWhisper的博客 169

WSL基础环境配置方案

通过以上步骤,您已经在 Windows 的 WSL 环境中成功搭建了一个完整的基础开发环境,包含 Docker、Kubernetes、Helm、kubectl、yq、Git 等工具。这套环境特别适用于在国内使用阿里云镜像服务部署和管理 Tekton,提升了开发和运维的效率和稳定性。

落魄书生的职业学习生涯 8876

vue制作快捷导航栏

data() {return {}},},methods: {

Jumy_S的博客 658

深度学习环境搭建以及DeepLabCut安装过程

文章目录 一、查询电脑硬件 安装GeForce驱动程序 二、环境搭建与软件安装 1.安装CUDA运算平台软件 2.安装cuDNN支持包 3.配置环境变量 三、 DeepLabCut环境配置 1.安装Anaconda 2.创建容器环境 3.激活容器环境 4.安装TensorFlow 5.验证TensorFlow是否安装成功 6...

m0_51136557的博客 3155

跨设备UI适配革命:shadcn-vue响应式组件深度解析

在现代多设备环境中,用户通过手机、平板、笔记本电脑等不同尺寸的设备访问应用已成为常态。shadcn-vue作为Vue生态中备受瞩目的UI组件库,通过创新的响应式设计理念,为开发者提供了构建完美跨设备体验的强大工具。本文将深入探讨如何利用shadcn-vue的响应式组件,实现从移动端到桌面端的无缝过渡,解决常见的布局断裂和交互冲突问题。 ## 响应式设计基础原理 shadcn-vue的响应式设计

gitblog_00568的博客 1189

PX4开发环境搭建(Ubuntu1804+QGC+Qt Creator )

文章目录前言一、安装环境二、PX4环境搭建1. 在虚拟机中安装Ubuntu2. 安装PX4环境(1)下载PX4源码:(2) 安装工具链(3) jMAVSim仿真(4) 编译验证三、安装QGC四、安装Qt Creator 前言 在这之前作者完全没接触过PX4,安装过程遇到了很多坑,而且每安装下载一个东西都要等好久,出现问题又要重新开始,前后折腾了四天才弄好,希望此文对大家有所帮助。 一、安装环境 ...

Beyonderwei的博客 9019

Unity四部曲(核心)

需要先改成Cube复杂的展开留到unity进阶再说。

ultraman1234566的博客 2797

Vue悬浮菜单终极指南:如何轻松实现优雅的浮动导航

还在为网站导航设计发愁吗?Vue-Float-Menu就是你的救星!这个功能强大的Vue悬浮菜单组件在前100字内就展现出了它的魅力——让用户轻松创建各种悬浮菜单效果,无论是侧边栏、快捷操作还是浮动导航,都能一键搞定。 ## 🚀 为什么选择Vue悬浮菜单组件 想象一下,你的网站有一个精致的悬浮菜单,用户无论滚动到页面哪个位置,都能快速访问重要功能。Vue-Float-Menu就是帮你实现这个

gitblog_00071的博客 834

DeepSeek+Dify之一安装部署

DeepSeek添加知识库

yilvyangguang520的博客 1544

Element | 快捷组件样式

在真正实际运用过程中需要模块化,提高组件的复用性。

weixin_69851346的博客 1088

python点云可视化

Python三种点云可视化方案:mayavi、matplotlib、CloudCompare。

叶子的博客 1万+

ROS从入门到精通6-2:gmapping激光建图与自定义建图功能包

本文用Turtlebot3实例直观介绍激光建图概念,并实现自定义建图功能包(自动建图与键盘手动控制建图)

FRIGIDWINTER的博客 2662

Vue-Tippy完全指南:打造惊艳的VueJS Tooltip体验

想要为你的Vue.js 3应用添加现代化、功能丰富的工具提示吗?Vue-Tippy 是你的完美选择!这个强大的 VueJS Tooltip 库基于流行的 Tippy.js 构建,提供了简单直观的 API 和卓越的用户体验。无论你是新手还是经验丰富的开发者,Vue-Tippy 都能帮助你快速创建美观、可访问的工具提示组件。 ## 🚀 什么是 Vue-Tippy? Vue-Tippy 是一个专为

gitblog_00415的博客 713

VSCode + QMT 量化交易完整解决方案!

🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值 。

**My Coding Family** 1326

VueCircleMenu组件深度解析:打造优雅交互式圆形导航

VueCircleMenu是一款基于Vue.js框架开发的创新圆形菜单组件,它通过独特的圆形布局设计和丰富的交互动效,为现代Web应用提供了既美观又实用的导航解决方案。作为Vue组件生态中的一颗明珠,这款圆形菜单工具能够显著提升用户界面的交互体验和视觉吸引力。 ## 组件核心功能概览 ### 多样化布局模式 VueCircleMenu支持六种不同的菜单布局方式,每种布局都能带来独特的视觉呈现效

gitblog_00281的博客 736

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Vue+ElementUI 导航组件

创建导航页组件 在components目录下新建一个navigation目录,在Navi目录中新建一个名为Navi.vue的组件。至此我们的目录应该是如下图所示: 然后我们修改main.js文件,修改后的文件如下 import Vue from 'vue' //import App from './App' import router from './rout...

weixin_30322405的博客 318

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

探索VueTailwind:打造响应式Vue与TailwindCSS的完美结合

探索VueTailwind:打造响应式Vue与TailwindCSS的完美结合 componentsFully responsive and beautiful HTML components made with VueJS and TailwindCSS.项目地址:https://gitcode.com/gh_mirrors/compon/components 项目介绍 VueTailwind...

gitblog_00035的博客 651

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

VueCircleMenu:打造惊艳视觉效果的圆形导航菜单组件

VueCircleMenu是一款基于Vue.js框架开发的创新圆形菜单组件,通过独特的圆形布局和丰富的交互效果,为现代Web应用提供了美观且功能强大的导航解决方案。无论您是正在开发个人博客、企业官网还是移动应用,这款组件都能显著提升用户界面的视觉吸引力。 ## 项目亮点展示 VueCircleMenu以其出色的视觉效果和灵活的配置选项脱颖而出。组件支持六种不同的菜单布局方式,包括顶部、底部、左

gitblog_00224的博客 299

【亲测免费】 Vue Floating Menu:一款轻量级、可自定义的浮動菜单组件

Vue Floating Menu:一款轻量级、可自定义的浮動菜单组件 在前端开发中,我们经常需要设计一些浮动元素,如悬浮按钮或菜单,以提供用户友好的交互体验。Vue Floating Menu 是一个专门为此场景设计的开源组件,它基于 Vue.js 框架,提供了高度的灵活性和定制性,让开发者可以快速地为他们的应用添加这样的功能。 项目简介 是由 yuanzhou3118 开发的一个轻量级的 Vu...

gitblog_00089的博客 1653

探索Protovue:Vue.js的原型构建神器

探索Protovue:Vue.js的原型构建神器 在快节奏的开发环境中,高效地搭建UI原型成为了设计师和开发者不可或缺的一项技能。今天,我们来深入了解一款专为Vue.js量身定制的组件库——Protovue,它旨在简化原型设计过程,提升你的开发效率。 项目介绍 Protovue,正如其名,是一个强大而灵活的原型组件库,为Vue.js应用打造。借助Protovue,你可以迅速构建出美观且功能齐全的U...

gitblog_00037的博客 953

Microi吾码界面设计引擎之基础组件用法大全【内置组件篇·上】

前面已经学习了如何快速集成界面引擎插件,也介绍的界面引擎的布局及基本用法,今天来学习系统内置组件的用法。系统内置了一些常用的基本组件,当然并不能满足所有需求,我们还提供了自定义组件,自定义组件具体用法后续会有介绍。内置组件基本囊括了80% 的组件,而且参数设置基本上是一致的,除了一些样式上的参数控制。

李赛赛的专栏 2598

Vue 3 中文文档完全指南:从零基础到高级开发的终极教程

Vue 3 中文文档是 Vue.js 3 官方文档的完整中文翻译版本,为中文开发者提供了最权威、最全面的学习资源。无论你是前端新手还是经验丰富的开发者,这份文档都能帮助你快速掌握 Vue 3 的核心概念、新特性和最佳实践。本指南将带你系统性地学习 Vue 3,从基础安装到高级功能,让你在最短时间内成为 Vue 3 开发高手。 ## 为什么选择 Vue 3?革命性的前端开发体验 Vue 3 是

gitblog_00022的博客 499
上一篇: el-dialog中调用resetFields()方法重置表单报错
下一篇: vue 与 vue-json-viewer 实现 JSON 数据可视化
水星记_
水星记_ 优质创作者: 编程框架技术领域 优质创作者: 编程框架技术领域
博客等级 码龄6年 13万+粉丝 212原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

水星记_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值