vue+elementui表格

加固定列 fixed

滚动条在fixed列下不能拖动

增加合计行:show-summary

将滚动条固定在合计行底部

由于不同浏览器滚动条高度不同,使用css判断浏览器类型,调用不同的样式

/* Target Safari and Chrome */
    @media screen and (-webkit-min-device-pixel-ratio:0) {
      /*table {*/
        /*color: blue;*/
      /*}*/
      .el-table--scrollable-x {
        .el-table__fixed {
          margin-bottom: 8px;
        }
      }
    }
    /* Target IE 10 */
    @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
      /*table {*/
        /*color: red;*/
      /*}*/
      .el-table--scrollable-x {
        .el-table__fixed {
          margin-bottom: 15px;
        }
      }
    }

完整代码

<template>
  <div id="formalResNegHeadman" class="content_bgibox">
    <!--评-->
    <div class="setup_bigbox">
      <div class="proinfobox">
        <span class="line_bigbox"></span>
        <span class="title_bigbox">标题</span>
      </div>
    </div>
    <div class="score_bigbox" >
      <el-table
        ref="somTable"
        :data="tableDataScore"
        show-summary
        border
        style="width: 100%" max-height="600">
        <el-table-column
          type="index"
          label="序号"
          width="50"
          fixed
          align="center">
        </el-table-column>
        <el-table-column
          prop="itemName"
          label="因素"
          width="150"
          fixed
          show-overflow-tooltip
          align="left">
        </el-table-column>
        <el-table-column
          prop="itemDesc"
          label="标准"
          width="200"
          fixed
          show-overflow-tooltip
          align="left">
        </el-table-column>
        <el-table-column
          prop="lessItemScore"
          label="最低分"
          width="70"
          fixed
          align="center">
        </el-table-column>
        <el-table-column
          prop="itemScore"
          label="最高分"
          width="70"
          fixed
          align="center">
        </el-table-column>
        <template v-for="(item,key) in tabScoreTitle" >
          <el-table-column :prop="item.column_name"
                           width="200"
                           :label="item.column_comment"
                           :key="key"
                           align="left">
            <template slot-scope="scope">
              <el-input v-model="scope.row[item.column_name]"
                  size="mini"
                  type="text"
                  @change="handleScore(scope)"
                  style="font-size: 15px;" :disabled="subStatus">
              </el-input>
            </template>
          </el-table-column>
        </template>
      </el-table>
      <!--提交按钮-->
      <div class="sub_btnbigbox">
        <el-button type="primary" class="sub_btn" @click="submitBtn" v-if="!orderStatus">提 交</el-button>
        <el-button type="primary" class="sub_btn" disabled v-else>已提交</el-button>
      </div>
      <!--提交按钮-->
    </div>
    <!--评分-->
  </div>
</template>
<script>
import { consultingReview } from '@/api'
export default {
  data () {
    return {
      pageSize: 1000, // 每页展示条数
      pageNo: 0,
      // 表头动态获取
      tabScoreTitle: [],
      // 每个评审项目的不同数据
      tableDataScore: [],
      checkList: [], // 评审数据
      orderStatus: false, // 命令状态
      reviewType: '',
      subStatus: false, // 是否可以输入
      scaleDecimal: this.$store.getters.authUser.scaleDecimal
    }
  },
  activated () {
    this.doLayout()
  },
  methods: {
    doLayout () {
      this.$nextTick(() => {
        this.$refs.somTable.doLayout()
      })
    },
    handleScore (scope) { // 录入分数
      let tenderId = scope.column.property // 投标人id
      let id = 0
      // let itemNameId = scope.row.itemNameId
      let lessItemScore = scope.row.lessItemScore
      let score = scope.row[tenderId]
      let totalScore = scope.row.itemScore
      // 评分小数位
      let flagRex = new RegExp('^0$|^0$|^(-)?[1-9]\\d{0,15}$|^(-)?[1-9]\\d{0,15}\\.{1}\\d{1,' + this.scaleDecimal + '}$|^(-)?0\\.{1}\\d{1,' + this.scaleDecimal + '}$')
      if (flagRex.test(score)) {
        if (score > totalScore) {
          this.$message({
            type: 'warning',
            message: '不能超过满分'
          })
          return
        }
        if (lessItemScore > score) {
          this.$message({
            type: 'warning',
            message: '不能低于最低分'
          })
          return
        }
        this.checkList.map((item) => {
          if (item.checkItemId === scope.row.itemNameId && item.tenderId.toString() === scope.column.property) {
            id = item.objectId
          }
        })
        let params = {
          checkScore: score,
          objectId: id
        }
        consultingReview.preservationUnqualified(params).then((res) => {
          this.checkList.map((its) => {
            if (its.objectId === params.objectId) {
              its.checkScore = params.checkScore
            }
          })
        })
      } else {
        this.$message({
          type: 'warning',
          message: '得分不能超过' + this.scaleDecimal + '位小数'
        })
      }
    },
    // 点击切换
    chooseAddr (index) {
      this.addrSelected = index
    },
    reviewResultsLists () { // 初始化数据
      let url = {
        pageNo: this.pageNo,
        pageSize: this.pageSize,
        checkType: this.reviewType
      }
      consultingReview.reviewResultsList2(url).then((res) => {
        this.tabScoreTitle = res.data.ResultTitle
        this.tableDataScore = res.data.ResultList
        this.checkList = res.data.checkList
        this.orderStatus = res.data.isHide === '1'
        this.subStatus = res.data.isHide === '1'
      })
      this.doLayout()
    },
    checkSample () {
      let reResult = false
      this.checkList.map((its) => {
        if (its.checkScore === null || its.checkScore === '') {
          console.log('未录入记录', its)
          reResult = true
        }
      })
      return reResult
    },
    submitBtn () {
      let url = {
        checkTypeId: this.reviewType
      }
      let backV = this.checkSample()
      if (!backV) {
        consultingReview.rationalitySubmit(url).then(() => {
          this.reviewResultsLists()
        })
      } else {
        this.$message({
          type: 'warning',
          message: '还未全部录入,请继续录入'
        })
      }
    },
    handleType () {
      this.reviewType = this.$route.params.type
    },
    init () {
      this.handleType()
      this.reviewResultsLists()
    }
  },
  mounted () {
    this.init()
    const a = this.$refs.somTable.$refs.footerWrapper
    a.addEventListener('scroll', () => {
      const left = a.scrollLeft
      this.$refs.somTable.$refs.bodyWrapper.scrollLeft = left
    })
  }
}
</script>
<style lang="less">
  #formalResNegHeadman{
    margin-top: 20px;
    .score_bigbox{
      padding:20px;
    }
    .el-table--scrollable-x .el-table__body-wrapper {
      overflow-x: hidden !important;
    }
    .el-table__body-wrapper {
      overflow-x: hidden !important;
    }
    .el-table__footer-wrapper {
      overflow-x: auto !important;
    }
    /*.el-table__fixed {*/
      /*margin-bottom: 14px;*/
    /*}*/

   /* Target Safari and Chrome */
    @media screen and (-webkit-min-device-pixel-ratio:0) {
      /*table {*/
        /*color: blue;*/
      /*}*/
      .el-table--scrollable-x {
        .el-table__fixed {
          margin-bottom: 8px;
        }
      }
    }
    /* Target IE 10 */
    @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
      /*table {*/
        /*color: red;*/
      /*}*/
      .el-table--scrollable-x {
        .el-table__fixed {
          margin-bottom: 15px;
        }
      }
    }
  }
</style>

感谢灵感来源:

在css中判断浏览器类型的5大方法盘点

ElementUI el-table 设置固定列,横向滚动条在固定列的位置上无法滚动的问题 

ElementUI el-table 设置固定列,横向滚动条在固定列的位置上无法滚动的问题 

<think>好的,我现在需要回答用户关于“Vue + ElementUI 表格列锁定”的问题。首先,我得确保自己正确理解用户的需求。用户可能在使用Element UI的表格组件时,希望某些列在水平滚动时保持固定,类似于Excel中的冻结列功能。这在实际开发中确实是一个常见需求,尤其是在处理大量数据表格时,保持关键信息可见非常重要。 首先,我应该回忆一下Element UI官方文档中关于表格组件的内容。Element UI的el-table组件确实支持列固定,通过给el-table-column设置fixed属性可以实现。fixed属性可以设置为"left"或"right",分别表示固定在左侧或右侧。例如,给第一列设置fixed="left",当水平滚动时,该列会保持固定不动。 接下来,我需要考虑用户可能遇到的问题或注意事项。比如,固定列可能会导致样式问题,特别是当表格有边框或斑马纹(stripe)时,固定列和非固定列之间的边框可能不对齐。此外,固定列的阴影效果在滚动时是否显示正确,或者在某些浏览器中是否有兼容性问题。这些都是开发者可能会遇到的,需要在回答中提及。 另外,用户可能需要知道如何同时固定多列。比如,前两列固定在左侧,最后一列固定在右侧。这时候需要为每个需要固定的列分别设置fixed属性,并且注意列的顺序是否正确,避免布局错乱。可能还需要调整z-index来确保固定列在滚动时覆盖其他内容。 然后,我应该举一个具体的例子,说明如何实现列固定。例如,一个包含姓名、年龄、地址等字段的表格,将姓名列固定在左侧,操作列固定在右侧。代码示例应该包括template中的el-table结构,并展示如何设置fixed属性。同时,提醒用户需要确保表格容器的宽度足够,否则可能会出现布局问题,比如固定列和滚动列重叠。 还需要提到动态固定列的情况,比如根据某些条件动态改变固定列。这时候可能需要使用动态绑定的方式,比如:fixed="isFixed ? 'left' : false",其中isFixed是一个响应式变量。这可以增加回答的实用性,覆盖更多使用场景。 另外,性能方面的问题也需要考虑。固定列可能会影响表格的渲染性能,尤其是在数据量很大时。虽然Element UI已经做了优化,但开发者还是需要注意避免不必要的重新渲染,比如合理使用key属性,或者分页加载数据。 最后,总结一下实现列锁定的步骤:引入Element UI组件,在el-table-column上设置fixed属性,处理可能的样式问题,测试滚动效果。同时,提供官方文档的链接,方便用户进一步查阅。 在检查过程中,还需要确保回答符合用户的要求:使用中文,结构清晰,分步骤说明,正确使用LaTeX格式(如果有数学内容的话,虽然这个问题可能不需要)。不过在这个问题中,可能不需要数学公式,但需要确保代码示例正确,使用适当的Markdown格式,比如代码块包裹在反引号中,并注明语言类型,如html或vue。 可能还需要提醒用户注意Element UI的版本,不同版本可能有不同的特性或bug,建议使用最新稳定版。此外,如果用户遇到特定问题,比如固定列在 Safari 中显示异常,可以建议检查CSS样式或查看GitHub上的issue。 总之,回答需要覆盖基本用法、示例代码、常见问题及解决方案,以及最佳实践建议,帮助用户有效实现表格列锁定功能。</think>在 Vue + ElementUI 中实现表格列锁定(固定列)可通过 `el-table` 组件的 `fixed` 属性实现。以下是分步说明和注意事项: --- ### 一、基础实现 1. **固定左侧列** 在需要固定的列(如“姓名”)上添加 `fixed="left"`: ```html <el-table :data="tableData" style="width: 100%"> <el-table-column prop="name" label="姓名" fixed="left" width="120"></el-table-column> <el-table-column prop="age" label="年龄" width="120"></el-table-column> <el-table-column prop="address" label="地址"></el-table-column> </el-table> ``` 2. **固定右侧列** 在需要固定的列(如“操作”)上添加 `fixed="right"`: ```html <el-table-column label="操作" fixed="right" width="120"> <template #default> <el-button>编辑</el-button> </template> </el-table-column> ``` --- ### 二、关键注意事项 1. **必须指定列宽度** 固定列的 `width` 属性必须显式定义,否则可能导致布局错乱。 2. **多列固定顺序** - 左固定列按代码顺序从左到右排列。 - 右固定列按代码顺序从右到左排列。 3. **样式问题** 若表格有边框(`border=true`)或斑马纹(`stripe=true`),需手动调整固定列与非固定列之间的边框对齐。 --- ### 三、动态控制固定列 通过绑定动态属性实现条件固定: ```html <el-table-column :fixed="isFixed ? 'left' : null"></el-table-column> ``` --- ### 四、完整示例 ```html <template> <el-table :data="tableData" border style="width: 100%"> <!-- 左固定列 --> <el-table-column prop="name" label="姓名" fixed="left" width="120"></el-table-column> <el-table-column prop="age" label="年龄" width="120"></el-table-column> <!-- 可滚动列 --> <el-table-column v-for="(item, index) in dynamicColumns" :key="index" :prop="item.prop" :label="item.label"></el-table-column> <!-- 右固定列 --> <el-table-column label="操作" fixed="right" width="150"> <template #default> <el-button size="small">编辑</el-button> <el-button type="danger" size="small">删除</el-button> </template> </el-table-column> </el-table> </template> <script> export default { data() { return { tableData: [ { name: '张三', age: 25, address: '北京' }, { name: '李四', age: 30, address: '上海' } ], dynamicColumns: [ { prop: 'address', label: '地址' } ] } } } </script> ``` --- ### 五、常见问题解决 1. **固定列阴影不显示** 检查表格容器是否设置 `overflow-x: auto`,或尝试强制刷新表格:`this.$refs.table.doLayout()`。 2. **列宽度不一致** 确保所有列(包括固定列)的 `width` 总和不超过表格容器宽度。 3. **性能优化** 大数据量时建议启用延迟渲染:`<el-table :data="data" :lazy="true">`。 --- ### 官方文档参考 - [ElementUI Table 固定列](https://element.eleme.cn/#/zh-CN/component/table#gu-ding-lie)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程界的小子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值