• 记一个“奇葩”需求的实现


    1、前言

    我们这边没有专门的产品经理,UI对产品的设计基本具有决定权,说实话,是有那么一点可怖的(前后改了很多次,差一点就改回原版了,我自己都觉得不好意思了🤣)。

    🤔有没有一种可能:我们UI体验过的产品少,缺少对产品以及用户行为的认识。设计出来的东西看似很华丽,其实缺失很多场景下的分析,不切合实际,这也正是产品经理需要做的工作之一。大多数人说的“用户体验”或许只是主观的、想当然的(俺也一样😮)。

    自从接触互联网开始我就在有意的学习怎么做产品,期间还考虑过转产品,永远不要拿业余的跟专业的比,没什么可比性,不成熟。继续保持思考、学习。

    下面记录一下我觉得比较有意思的、会引起思考的需求,所用技术:vuevue-routerelement-ui

    2、需求:

    导航菜单(el-menu组件)竖向展示的

    1. 鼠标移入一级菜单展示下面的子菜单,移出则收起来(手风琴模式,正常状态下只保持一个菜单处于展开状态,手动鼠标悬浮展开的不算)

    2. 选中某个子菜单时高亮对应的一级菜单,并且当鼠标移出高亮的这个菜单模块时不折叠,但是可以点击一级菜单进行折叠(注意:跟第一条有区别)

    3、问题:

    1. element-ui的导航组件子菜单打开的触发方式可以通过 menu-trigger 参数控制,但是,只在菜单是水平展示(horizontal)的情况下生效。嘶~! 我不禁暗想🤔:垂直模式滑动展开真的会有系统这么做吗?(只能自己修改了)

    2. unique-opened 参数可以控制是否只保持一个子菜单展开,但是在没有子菜单的情况下失效(需要手动修改)

    4、思路分析:

    导航菜单使用递归el-submenu组件实现

    1. 鼠标滑动展开关闭需求:
    • el-submenu 组件编写鼠标移入移出事件(mouseentermouseleave),拿到indexPath,调用openclose方法打开或者折叠菜单(注意:没有子菜单的一级菜单鼠标移入移出不做处理)
    1. 只保持一个菜单处于展开状态
    • 先配置 unique-opened 参数为 false ,以保证 openedMenus 只有一个( openedMenusel-menu内部维护的属性, 可以自行打印看一下)

    一开始我想在子菜单展开折叠的回调事件(openclose)里写逻辑判断,但是不知道什么原因回调事件不触发(注意:open方法open事件不一样,组件三大要素:属性、事件、方法),所以我就考虑在select回调事件里写逻辑了

    • 在菜单激活的select回调事件中,让上一个打开的菜单调用close方法关闭。(这里需要记录上次打开菜单的index,这里我使用sessionStorage记录)

    5、代码展示:

    只展示代码片段,仅供参考

    sessionStorage使用自己封装的,之前文章有写过,感兴趣的可以看一下掘金文章

    • el-submenu 组件
    menuEnter() {
      // isNest 是否还有子菜单 true:没有子菜单 false:有子菜单
      if (!this.isNest && this.item.alwaysShow) {
        // basePath: 一级菜单
        this.$emit('handleOpen', this.basePath)
      }
    }
    
    menuLeave() {
      // 存在子菜单,并且不是打开状态的菜单,鼠标离开的时候需要合起来
      if (!this.isNest && !this.curMenuIsOpened) {
        // basePath: 一级菜单
        this.$emit('handleClose', this.basePath)
      }
    }
    
    • el-menu 组件
    // 登录系统的时候,记录展开的菜单信息,
    // 在 mounted 里面获取 openedMenus ,并记录信息
    mounted() {
      // 获取当前展开的菜单 - array
      // 手风琴模式,只有一个展开菜单
      
      // openedMenus 是内部属性
      const {openedMenus = []} = this.$refs.menuRef;
      
      if (openedMenus && openedMenus.length > 0) {
        // 获取展开菜单的 index
        const index = openedMenus[0];
        sessionStorage.put('preActiveMenu', index)
      }
    }
    
    methods: {
      handleOpen(indexPath) {
        // 调用 open 方法, 打开close,
      	this.$refs.menuRef.open(indexPath);
      }
    
      handleClose(indexPath) {
        // 调用 close 方法, 关闭close
      	this.$refs.menuRef.close(indexPath);
      }
    
      handlerSelect(index, indexPath) {
        // 1. 获取上次激活的菜单信息
        const _preActiveMenu = sessionStorage.get('preActiveMenu') || '';
        if (_preActiveMenu) {
          // 如果存在,则关闭该菜单,再打开新的
          this.$refs.menuRef.close(_preActiveMenu);
        }
    
        // 2. 记录这次激活的菜单信息
        if (indexPath.length > 0) {
          sessionStorage.put('preActiveMenu', indexPath[0])
        }
      }
    }
    

    6、最终效果展示:

    总结

    用了UI框架之后就不可避免的会跟产品设计风格向左,这就需要在框架基础之上进行修改。框架也是一个个组件组成的,抓住组件设计的三要素:属性、事件、方法,了解框架组件的工作原理,就可以轻松的进行修改啦🎉🎉


    我是 甜点cc

    热爱前端,也喜欢专研各种跟本职工作关系不大的技术,技术、产品兴趣广泛且浓厚,等待着一个创业机会。主要致力于分享实用技术干货,希望可以给一小部分人一些微小帮助。

    我排斥“新人迷茫,老人看戏”的现象,希望能和大家一起努力破局。营造一个良好的技术氛围,为了个人、为了我国的数字化转型、互联网物联网技术、数字经济发展做一点点贡献。数风流人物还看中国、看今朝、看你我

  • 相关阅读:
    【CSDN RSS订阅】将你的博客订阅至个人网站
    接口回调中的次数判断方法
    为什么Redis默认序列化器处理之后的key会带有乱码?
    【LRUCache】Python缓存装饰器
    Vue3.0第一天
    3.Python-用Python实现MySQL数据库的增删改查
    【Redis核心知识】实现秒杀的三种方案
    小程序常用组件小结
    RabbitMQ:死信队列
    基于双向长短期记忆 BiLSTM 实现股票单变量时间序列预测(PyTorch版)
  • 原文地址:https://www.cnblogs.com/all-smile/p/16652414.html