当前位置: 首页 > article >正文

vue3封装一个悬浮操作固定列表格组件(性能版)

设计给的理由:再不需要操作按钮列时想要table表格看到更多列信息

方案1:通过js控制并计算位置
方案2:使用css控制节约性能

表格组件

<template>
  <el-table
    :data="tableData"
    style="width: 100%"
    @row-mouseenter="handleMouseEnter"
    @row-mouseleave="handleMouseLeave"
  >
    <!-- 数据列 -->
    <el-table-column prop="date" label="Date" width="150" />
    <el-table-column prop="name" label="Name" width="120" />
    <el-table-column prop="sex" label="Sex" width="120" />
    <el-table-column prop="city" label="City" width="120">
      <template #default="{ row }">
        <div class="cell-content">
          {{ row.city }}
          <!-- 操作按钮容器 -->
          <div class="operation-overlay" :class="{ active: activeRow === row }">
            <el-button
              link
              type="primary"
              size="small"
              @click.stop="handleDetail(row)"
            >
              详情
            </el-button>
            <el-button
              link
              type="primary"
              size="small"
              @click.stop="handleEdit(row)"
            >
              编辑
            </el-button>
          </div>
        </div>
      </template>
    </el-table-column>
  </el-table>
</template>

<script lang="ts" setup>
import { ref } from "vue";
// 当前激活行
const activeRow = ref(null);
const tableData = ref([
  { date: "2023-01-01", name: "John", city: "New York", sex: "男" },
  { date: "2023-02-01", name: "Alice", city: "London", sex: "男" },
  { date: "2023-03-01", name: "Bob", city: "Tokyo", sex: "女" },
]);

const handleMouseEnter = (row) => {
  activeRow.value = row;
};

const handleMouseLeave = () => {
  activeRow.value = null;
};

const handleDetail = (row) => {
  console.log("详情操作", row);
};

const handleEdit = (row) => {
  console.log("编辑操作", row);
};
</script>

<style scoped>
/* 单元格内容容器 */
.cell-content {
  display: block;
  width: 100%;
  height: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  position: relative;
}

/* 操作按钮覆盖层 */
.operation-overlay {
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 10px;
  background: rgba(255, 255, 255, 0.95);
  backdrop-filter: blur(2px);
  box-shadow: -5px 0 15px rgba(255, 255, 255, 0.9);
  opacity: 0;
  transition: opacity 0.3s ease;
  pointer-events: none;
}

/* 激活状态 */
.operation-overlay.active {
  opacity: 1;
  pointer-events: auto;
}

/* 按钮样式优化 */
:deep(.operation-overlay .el-button) {
  margin-left: 0;
  padding: 0 5px;
  position: relative;
  z-index: 2;
}

/* 行悬停效果 */
:deep(.el-table__body tr:hover td) {
  background: #f5f7fa !important;
}

/* 最后一列特殊处理 */
:deep(.el-table__body td:last-child .cell) {
  overflow: visible;
  padding-right: 0 !important;
}
/* 动态宽度适配: */
.operation-overlay {
  min-width: 120px; /* 根据按钮总宽度设置 */
  justify-content: flex-end;
}
/* 性能优化版本(纯CSS实现): */
/* 使用纯CSS实现 */
:deep(.el-table__body tr:hover td:last-child .operation-overlay) {
  opacity: 1;
  pointer-events: auto;
}
</style>

效果图
悬浮前:

 

悬浮后:

点击操作后:


http://www.kler.cn/a/562407.html

相关文章:

  • 声明式UI差分刷新机制的原理,应用场景及优缺点
  • 计组笔记day-01
  • 点云配准技术的演进与前沿探索:从传统算法到深度学习融合(1)
  • DeepSeek+谷云科技智能体,快速构建企业知识问答
  • CryptoJS库中WordArray对象支持哪些输出格式?除了toString() 方法还有什么方法可以输出吗?WordArray对象的作用是什么?
  • Vue 3中的路由和Vue Router 4有哪些变化?
  • 计算机网络————(三)
  • Java Web应用中的跨站脚本攻击(XSS)防护策略
  • linux-c 字节序问题--大小端
  • Html 5简介(学习笔记)
  • BIO系统调用strace查看IO阻塞
  • 【Java 基础】-- Java 接口中的 @Public 和 @FunctionalInterface 注解详解
  • SpringBoot整合sharding-jdbc 实现分库分表操作
  • Android SDK封装打包流程详解
  • Flutter - 基础Widget
  • 如何优化频繁跳槽后的简历?
  • 华为hcia——Datacom实验指南——二层交换原理
  • 企业级服务器如何初始化数据磁盘
  • C#与AI的交互(以DeepSeek为例)
  • STM32 最小系统