循环列表(如el-tree)中鼠标移入移出时对应删除icon的显示隐藏效果实现

331 阅读1分钟

背景

最近的一次需求评审中,听到产品提出了一个交互方式:“删除icon默认隐藏,鼠标移入后才显示。”我问,“让他直接显示着不成吗?非要给前端找事儿做”,他的回答是:

SCR-20220913-tii-2.png

好吧。于是我就在想,“鼠标移入”最直观的想法就是css中的hover关键字啊。但是!需要做的是“删除icon”这个组件的显示和隐藏耶,又不是只是背景颜色background-color的变化。所以,要用到JS咯。

el-tree中的效果实现

利用mouseentermouseenter动态改变新增的一个del字段来控制。

mouseenter(node){
  this.$set(node, 'del', true)
},
mouseleave(node){
  this.$set(node, 'del', false)
}

相对应的,HTML中写成如下:

<el-tree :data="dataList" >
  <span class="custom-tree-node" slot-scope="{ node, data }" 
        @mouseenter="mouseenter(node)" @mouseleave="mouseleave(node)">
    <el-button v-show="node.del" type="text" size="mini" @click="() => remove(node, data)">
      Delete
    </el-button>
  </span>
</el-tree>

上面的代码,不好理解的地方在于:

  1. 如何实现在已知的树结构中,鼠标移入某叶子节点,显示其对应的删除icon。
  2. 实现的方式用到了el-tree中的slot-scope关键字使其取出对应的node节点。

完整参考代码

那么,引申一下,在使用v-for循环展示的列表结构中,如何实现鼠标移入移出过程中对应删除icon的显示和隐藏呢?

普通v-for循环列表中的效果实现

同理嘛,只要能找到节点的对应方式就好了。elementUI中使用的是slot-scope,v-for也有自己的item呀~~

v-for="(item,index) in itemsList" //item指向了列表中每一个具体节点内容

那么实现的代码如下:

<div v-for="(item, index) in itemsList"
    :key="item.id"
    @mouseenter="mouseenter(item)"
    @mouseleave="mouseleave(item)"
>
<div class="delete" v-show = "item.del"></div>
</div>

<style>
    ...
    mouseenter(node){
      this.$set(node, 'del', true)
    },
    mouseleave(node){
      this.$set(node, 'del', false)
    },
    ...
</style>

另外,上述代码中的index是从0开始计数的第几条数据。可根据这个性质做有序列表的展示。

例如,

<div v-for="(item, index) in itemsList"
    :key="item.id"
>
    <div class="number">{{index+1}}</div>
</div>