# 因使用hover如果频率移入太快,导致元素出现闪动的情况,所以可以通过鼠标移入移出事件来控制,上代码:

1、鼠标移入事件:onmouseover

2、鼠标移出事件:onmouseout

4、鼠标进入事件:onmouseenter

5、鼠标离开事件:onmouseleave

一.、HTML部分:

          <div class="menu-list-wrap">
            <ul class="menu_list">
              <li class="menus_item" v-for="(item, index) in menuDataTest" :key="index"
                @mouseover="showSubmenu(item, index)" @mouseout="hideSubmenu(index)">
                <div class="menu_item_name">{{ item.name }}</div>
                <div class="secondary-menu" v-show="item.columns.length > 0 && showSubMenu && activeSubmenu === index">
                  <div class="menu-wrap" v-for="(column, columnIndex) in item.columns" :key="columnIndex">
                    <span>{{ column.name }}</span>
                  </div>
                </div>
              </li>
            </ul>
          </div>

 二、 js部分

export default {
  data() {
    return {
      menuDataTest: [
        {
          name: '导航1',
          columns: [
            {
              name: '导航1二级菜单1111',
            },
            {
              name: '导航1二级菜单222',
            },
            {
              name: '导航1二级菜单1111',
            }
          ],
        },
        {
          name: '导航2',
          columns: [
            {
              name: '导航2二级菜单1111',
            },
            {
              name: '导航2二级菜单222',
            },
            {
              name: '导航2二级菜单1111',
            }
          ],
        },
        {
          name: '导航3',
          columns: [
            {
              name: '导航3二级菜单1111',
            },
            {
              name: '导航3二级菜单222',
            },
            {
              name: '导航3二级菜单1111',
            }
          ],
        },
        {
          name: '导航4',
          columns: [
            {
              name: '导航4二级菜单1111',
            },
            {
              name: '导航4二级菜单222',
            },
            {
              name: '导航4二级菜单1111',
            }
          ],
        },
      ],

      menuTimer: null, // 定时器
      activeSubmenu: null, // 当前要展示的菜单
      showSubMenu: false, // 控制二级菜单显示隐藏值

},
methods: {
    // 鼠标移入
    showSubmenu(item, index) {
      const _this = this;
      clearTimeout(_this.menuTimer)
      if (item.columns && item.columns.length > 0) {
        _debounce(function () {
          _this.activeSubmenu = index;
          _this.showSubMenu = true
        }, 200);
      }

    },

    // 鼠标移出
    hideSubmenu(index) {
      const _this = this;
      if (_this.activeSubmenu === index) {
        _this.menuTimer = setTimeout(() => {
          _this.activeSubmenu = null;
          _this.showSubMenu = false
        }, 200)
      }
    },
}

三.、css部分:

/** 菜单区域 */
.menu-list-wrap {
  display: inline-block;
  line-height: 80px;
  vertical-align: top;
  text-align: center;
}

.menu_list {
  display: flex;
  justify-content: space-between;

  .menu_item_name {
    font-family: "微软雅黑 Bold", "微软雅黑 Regular", "微软雅黑", sans-serif;
    display: inline-block;
    color: #333;
    font-weight: 400;
    font-style: normal;
    margin: 0 16px;
    cursor: pointer;
    height: 80px;
  }
}

.menu_item_name:after {
  display: block;
  content: "";
  height: 4px;
  width: 64px;
  position: absolute;
  bottom: 0;
  margin: 0 auto;
  background: #005CD8;
  opacity: 0;
  transition: transform 0.2s ease-out, opacity 0.2s ease-out;
  transform-origin: 50% 50%;
  transform: scale(0.01, 1);
}

.menus_item:hover .menu_item_name:after {
  transform: scale(1, 1);
  opacity: 1;
}

.menus_item:hover .menu_item_name {
  color: #005CD8;
  font-weight: 700;
}

.secondary-menu {
  display: flex;
  flex-direction: row;
  justify-content: center;
  width: 100vw;
  position: fixed;
  left: 0px;
  z-index: 2;
  background: #fff;
  box-shadow: 0 4px 10px 0 rgb(0 0 0 / 10%);
  animation: secondary-menu-show 0.2s ease-out both;
  text-align: left;
  padding: 0 100px 0 80px;
}

.menu-wrap {
  flex: 1;
  margin: 25px;
  animation: secondary-menu-show 0.3s ease-out both;
}

四、 优化:这里使用了防抖函数,为了防止频繁操作

/* 防抖函数 */
let timeoutValue = null // 创建一个标记用来存放定时器的返回值
let countValue = 0;
export function _debounce(fn, wait = 1000, immediate = false) {
  return function () {
    const args = arguments;
    if (immediate) {
      if (countValue == 0) {
        fn.apply(this, arguments)
        countValue++;
      } else {
        if (timeoutValue) {
          clearTimeout(timeoutValue) // 每当用户输入的时候把前一个 setTimeout clear 掉
        }

        timeoutValue = setTimeout(() => {
          fn.apply(this, arguments)
        }, wait)
      }
    } else {
      if (timeoutValue) {
        clearTimeout(timeoutValue) // 每当用户输入的时候把前一个 setTimeout clear 掉
      }
      timeoutValue = setTimeout(() => {
        fn.apply(this, arguments)
      }, wait)
    }

  }()
}

总结:这里只是简单的小例子,具体样式还需根据项目实现,次代码可解决频繁移入事件中展示不同的东西使用,做了异步和频繁移入处理,防止出现闪屏情况,影响用户体验。

GitHub 加速计划 / vu / vue
105
18
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:1 个月前 )
9e887079 [skip ci] 1 年前
73486cb5 * chore: fix link broken Signed-off-by: snoppy <michaleli@foxmail.com> * Update packages/template-compiler/README.md [skip ci] --------- Signed-off-by: snoppy <michaleli@foxmail.com> Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 1 年前
Logo

新一代开源开发者平台 GitCode,通过集成代码托管服务、代码仓库以及可信赖的开源组件库,让开发者可以在云端进行代码托管和开发。旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐