VUE开发小技巧:hover出来的图标使用ElementUI的dropdown

2,218 阅读2分钟

一、前言-问题描述🌟

当我们把鼠标移动到某个区域,hover显示出功能图标后,我们点击图标弹出功能菜单,但当鼠标移出hover区域或者移动到弹出的功能菜单时,原来的功能图标消失了,这显然不是我们需要的效果,效果如下:

现象.gif 现在我们希望当弹出功能菜单后,鼠标移出hover区域或者移动到弹出的功能菜单时,此时hover区域的功能图标不消失,我们需要怎样实现了?

二、解决方案🙉

解决思路

我们创建一个class,使之和hover动作的样式一致,当我们点击功能图标弹出功能菜单时,我们给hover区域的dom元素加上这个class,而当功能菜单弹窗消失时,我们就去掉这个class

具体实现

先梳理一下上面gif图的html结构:

class="app-list"的dom节点下有多个class="app-item"的dom, 其中每个列表项的应用ref="'app'+item.app_id",这样我们就可以通过app_id找到每个列表项。当我们把鼠标hover至每个app-item时,app-item中class="app-options"的dom会显示出来,app-options中包含了一个class="more-btn"的dom节点,该节点使用了ElementUI的dropdown下拉菜单组件,当点击more-btn时,下拉菜单显示。

<ul class="app-list">
    <li class="app-item" :ref="'app'+item.app_id" v-for="item in appList" :key="item.app_id" @click="toAppManage(item.app_id)">
      <div class="ipu-flex">
        <img class="app-logo" :src="item.app_logo">
        <div class="ipu-flex ipu-flex-vertical ipu-flex-justify-space ipu-flex-grow-1">
          <div class="app-name">{{item.app_name}}</div>
          <div class="create-time">{{item.create_date}}</div>
        </div>
      </div>
      <div class="app-description">{{item.app_desc}}</div>
      <div class="ipu-flex-grow-1"></div>
      <div class="app-options" @click.stop>

        <el-tooltip  effect="dark" content="预览" placement="top" :enterable="false">
          <i class="ri-eye-fill"></i>
        </el-tooltip>

        <el-dropdown trigger="click" @command="onAppAction" placement="bottom-start" @visible-change="visibleChange($event, item.app_id)">
          <div class="more-btn">
            <i class="ri-more-fill"></i>
          </div>

          <el-dropdown-menu slot="dropdown">
            <el-dropdown-item class="ipu-flex-middle" :command="{type:'set', appId: item.app_id}">
              <span class="child-action-name">应用设置</span>
            </el-dropdown-item>
            <el-dropdown-item class="ipu-flex-middle" :command="{type:'delete', appId: item.app_id}">
              <span class="child-action-name">删除应用</span>
            </el-dropdown-item>
          </el-dropdown-menu>
        </el-dropdown>

      </div>
    </li>
  </ul>

再来看CSS部分的代码,CSS部分采用SCSS预处理器编写:

.app-options在普通状态下由于transform: translateY(42px);向下移了42px而隐藏,当鼠标移至.app-item上时,我们给它的hover事件上设置了transform: translateY(4px);这时.app-options由于上移而显示,同时我们在.app-item上定义了一个.select样式,它的样式与hover事件的样式一致。

.app-list {
        margin-top: 30px;
        display:flex;
        flex-wrap: wrap;
        gap: 20px;
        .app-item {
          overflow: hidden;
          cursor: pointer;
          position: relative;
          width: 258px;
          height: 206px;
          padding:20px;
          background: #FFFFFF;
          border: 1px solid #F2F6FC;
          border-radius: 4px;
          display: flex;
          flex-direction: column;
          &:hover  {
            box-shadow: 0px 2px 12px rgba(0, 0, 0, 0.06);
            .app-options {
              transform: translateY(4px);
            }
          }
          &.select {
            box-shadow: 0px 2px 12px rgba(0, 0, 0, 0.06);
            .app-options {
              transform: translateY(4px);
            }
          }
          .app-logo {
            background: #fff;
            border-radius: 6px;
            width: 50px;
            height: 50px;
            margin-right: 14px;
          }
          .app-name {
            font-size: 16px;
            line-height: 24px;
            color: #606266;
            overflow: hidden;
            white-space: nowrap;
            text-overflow: ellipsis;
          }
          .create-time {
            font-size: 14px;
            line-height: 22px;
            color: rgba(0, 0, 0, .45);
          }
          .app-description {
            margin-top: 19px;
            font-size: 12px;
            line-height: 20px;
            color: #909399;
            display: -webkit-box;
            -webkit-line-clamp: 3;
            -webkit-box-orient: vertical;
            overflow: hidden;
            text-overflow: ellipsis;
          }
          .app-options {
            align-self: flex-end;
            display: flex;
            justify-content: flex-end;
            transform: translateY(42px);
            transition: transform .3s ease-in-out;
            i {
              font-size: 20px;
              line-height: 20px;
              color: rgba(144, 147, 153, 1);
            }
            .more-btn {
              margin-left:20px;
            }
          }
        }
      }

JS部分梳理:

ElementUI的dropdown下拉菜单组件可以通过监听visible-change事件,获取下拉菜单的状态,出现则为 true,隐藏则为 false。于是我们在组件上添加@visible-change="visibleChange($event, item.app_id),并传入app_id。我们可以通过app_id找到对应的dom节点,然后根据下拉菜单的状态给此dom节点添加或移除select样式

visibleChange(e, appId) {
    if (e) {
      this.$refs['app' + appId][0].classList.add('select')
    } else {
      this.$refs['app' + appId][0].classList.remove('select')
    }
}

最终我们实现了当弹出功能菜单后,鼠标移出hover区域或者移动到弹出的功能菜单时,此时hover区域的功能图标不消失的效果,如下图:

结果.gif

三、总结与举一反三✨

创建一个class,使之和hover动作的样式一致,当我们点击功能图标弹出功能菜单时,我们给hover区域的dom元素加上这个class,而当功能菜单弹窗消失时,我们就去掉这个class。通过这个原理我们实现了想要的效果,类似的ElementUI的 Popover 弹出框组件、Tooltip 文字提示组件,我们想在移动到弹出框、文字提示区域时,原来hover显示的图标不消失,都可以运用此技巧~