記一個「奇葩」需求的實現

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

熱愛前端,也喜歡專研各種跟本職工作關係不大的技術,技術、產品興趣廣泛且濃厚,等待著一個創業機會。主要致力於分享實用技術乾貨,希望可以給一小部分人一些微小幫助。

我排斥「新人迷茫,老人看戲」的現象,希望能和大家一起努力破局。營造一個良好的技術氛圍,為了個人、為了中國的數字化轉型、互聯網物聯網技術、數字經濟發展做一點點貢獻。數風流人物還看中國、看今朝、看你我