当前位置:   article > 正文

用vue+element实现表格键盘上下键单选中行效果_vue3实现上下箭头选中

vue3实现上下箭头选中

使用element的table组件,如果还想要实现上下键选中行效果的话,可以试试以下方法,主要是通过监听键盘事件实现的

如果还需要表格上下键时保持被选中行一直在视野中的话,可以在监听事件中根据当前行的位置动态设置表格的滚动距离实现,现在先不加了,等有时间再完善

1、首先定义一个变量,来确定当前被点击行的index,再根据监听到的是上键或者下键,递减或递增此变量,通过element table的toggleRowSelection方法实现对当前行的勾选选中,具体代码作用已在备注中

代码如下:

keyUp(e) {
    // 表格为空,不执行下方 
  if (this.tableData.length == 0) return
  
  if (e.keyCode == 40) { // 下键
    let refsElTable = this.$refs.singleTable
    this.$nextTick(() => {
      if (this.selectedRow.length == 0) { // 如果当前没有选中行,则直接选中第一个
        this.selectedIndex = 0
      } else if (this.selectedIndex == this.tableData.length - 1) { // 如果选中的是最后一行了,那么下一行选中的是第一行
        this.selectedIndex = 0
      } else { // 正常递增
        this.selectedIndex++
      }
      if (!refsElTable) return
      let findRow = this.selectedRow.find(c => c.rowIndex == this.selectedIndex); //找出当前选中行
      //如果只有一行且点击的也是这一行则取消选择 否则清空再选中当前点击行
      if (findRow && this.selectedRow.length === 1) {
        refsElTable.toggleRowSelection(this.tableData[this.selectedIndex], false);
        return;
      }
      refsElTable.clearSelection();
      refsElTable.toggleRowSelection(this.tableData[this.selectedIndex]); // 把现在当前行勾选
    })
  } else if (e.keyCode == 38) { // 上键
    let refsElTable = this.$refs.singleTableleft
    this.$nextTick(() => {
      if (this.selectedRow.length == 0) { // 当前没有选中行,则直接选中第一个
        this.selectedIndex = 0
      } else if (this.selectedIndex == 0) { // 如果选中的是第一行了,那么下一行选中的是最后一行
        this.selectedIndex = this.tableData.length - 1
      } else { // 正常递减
        this.selectedIndex--
      }
      if (!refsElTable) return
      let findRow = this.selectedRow.find(c => c.rowIndex == this.selectedIndex); //找出当前选中行
      //如果只有一行且点击的也是这一行则取消选择 否则清空再选中当前点击行
      if (findRow && this.selectedRow.length === 1) {
        refsElTable.toggleRowSelection(this.tableData[this.selectedIndex], false);
        return;
      }
      refsElTable.clearSelection();
      refsElTable.toggleRowSelection(this.tableData[this.selectedIndex]); // 把现在当前行勾选
    })
  }
  
},
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

2、增加表格相应的方法,分别为针对于选中行的样式改变、给每行数据添加不可枚举属性、单击选中行以及选项改变之后对已选行的保存

// 表格方法
    rowClassName({ row, rowIndex }) {
      let rowName = "",
        findRow = this.selectedRow.find(c => c.rowIndex === row.rowIndex);
      if (findRow) {
        rowName = "rowStyle "; // 可以通过此处给选中行一个class,根据自己需求更改样式
      }
      return rowName; //也可以再加上其他类名 如果有需求的话
    },
    rowStyle({ row, rowIndex }) {
      Object.defineProperty(row, "rowIndex", { // 给每行添加不可枚举属性rowIndex来标识当前行
        value: rowIndex,
        writable: true,
        enumerable: false
      });
    },
    clickEvent(row, column, event, params) {
      let refsElTable = this.$refs.singleTable; // 获取表格对象
      let findRow = {}
      findRow = this.selectedRow.find(c => c.rowIndex == row.rowIndex); //找出当前选中行
      //如果只有一行且点击的也是这一行则取消选择 否则清空再选中当前点击行
      if (findRow && this.selectedRow.length === 1) {
        refsElTable.toggleRowSelection(row, false);
        return;
      }
      refsElTable.clearSelection();
      refsElTable.toggleRowSelection(row);
    },
    handleSelectionChange(rows) {
      this.selectedRow = rows; // 保存已选择行
    },
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

3、加上其他内容,完整代码

<template>
  <div>
    <el-table
      ref="singleTable"
      class="table"
      :data="tableData"
      :row-class-name="rowClassName"
      :row-style="rowStyle"
      @row-click="clickEvent"
      @selection-change="handleSelectionChange"
      >
      <el-table-column
        v-for="(item, index) in tableColumn"
        :key="index"
        :property="item.englishName"
        :label="item.columnName"
        :min-width="item.width"
        >
        <template slot-scope="scope">
          {{scope.row[item.englishName] ? scope.row[item.englishName] : '-'}}
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
export default {
  data() {
    return {
      tableData: [
        {
          'code': '100001',
          'name': '张一',
          'age': 11,
          'grade': '高一'
        },
        {
          'code': '100002',
          'name': '张二',
          'age': 12,
          'grade': '高二'
        },
        {
          'code': '100003',
          'name': '张三',
          'age': 13,
          'grade': '高三'
        },
        
      ],
      tableColumn: [ // 表格显示的都是哪些列
        {englishName: 'code', columnName: '编号', width: '70'},
        {englishName: 'name', columnName: '姓名', width: '70'},
        {englishName: 'age', columnName: '年龄', width: '70'},
        {englishName: 'grade', columnName: '年级', width: '70'},
      ],
      selectedRow: [], // 当前已选择行
      selectedIndex: 0, // 当前选择行的index
    }
  },
  mounted() {
    addEventListener('keyup', this.keyUp)
  },
  beforeDestroy() {
    removeEventListener('keyup', this.keyUp)
  },
  methods: {
    keyUp(e) {
        // 表格为空,不执行下方 
      if (this.tableData.length == 0) return
      
      if (e.keyCode == 40) { // 下键
        let refsElTable = this.$refs.singleTable
        this.$nextTick(() => {
          if (this.selectedRow.length == 0) { // 如果当前没有选中行,则直接选中第一个
            this.selectedIndex = 0
          } else if (this.selectedIndex == this.tableData.length - 1) { // 如果选中的是最后一行了,那么下一行选中的是第一行
            this.selectedIndex = 0
          } else { // 正常递增
            this.selectedIndex++
          }
          if (!refsElTable) return
          let findRow = this.selectedRow.find(c => c.rowIndex == this.selectedIndex); //找出当前选中行
          //如果只有一行且点击的也是这一行则取消选择 否则清空再选中当前点击行
          if (findRow && this.selectedRow.length === 1) {
            refsElTable.toggleRowSelection(this.tableData[this.selectedIndex], false);
            return;
          }
          refsElTable.clearSelection();
          refsElTable.toggleRowSelection(this.tableData[this.selectedIndex]); // 把现在当前行勾选
        })
      } else if (e.keyCode == 38) { // 上键
        let refsElTable = this.$refs.singleTableleft
        this.$nextTick(() => {
          if (this.selectedRow.length == 0) { // 当前没有选中行,则直接选中第一个
            this.selectedIndex = 0
          } else if (this.selectedIndex == 0) { // 如果选中的是第一行了,那么下一行选中的是最后一行
            this.selectedIndex = this.tableData.length - 1
          } else { // 正常递减
            this.selectedIndex--
          }
          if (!refsElTable) return
          let findRow = this.selectedRow.find(c => c.rowIndex == this.selectedIndex); //找出当前选中行
          //如果只有一行且点击的也是这一行则取消选择 否则清空再选中当前点击行
          if (findRow && this.selectedRow.length === 1) {
            refsElTable.toggleRowSelection(this.tableData[this.selectedIndex], false);
            return;
          }
          refsElTable.clearSelection();
          refsElTable.toggleRowSelection(this.tableData[this.selectedIndex]); // 把现在当前行勾选
        })
      }
      
    },
    // 表格方法
    rowClassName({ row, rowIndex }) {
      let rowName = "",
        findRow = this.selectedRow.find(c => c.rowIndex === row.rowIndex);
      if (findRow) {
        rowName = "rowStyle "; // 可以通过此处给选中行一个class,根据自己需求更改样式
      }
      return rowName; //也可以再加上其他类名 如果有需求的话
    },
    rowStyle({ row, rowIndex }) {
      Object.defineProperty(row, "rowIndex", { // 给每行添加不可枚举属性rowIndex来标识当前行
        value: rowIndex,
        writable: true,
        enumerable: false
      });
    },
    clickEvent(row, column, event, params) {
      let refsElTable = this.$refs.singleTable; // 获取表格对象
      let findRow = {}
      findRow = this.selectedRow.find(c => c.rowIndex == row.rowIndex); //找出当前选中行
      //如果只有一行且点击的也是这一行则取消选择 否则清空再选中当前点击行
      if (findRow && this.selectedRow.length === 1) {
        refsElTable.toggleRowSelection(row, false);
        return;
      }
      refsElTable.clearSelection();
      refsElTable.toggleRowSelection(row);
    },
    handleSelectionChange(rows) {
      this.selectedRow = rows; // 保存已选择行
    },
  }
}
</script>

<style>

</style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/114586
推荐阅读
相关标签
  

闽ICP备14008679号