在Vue中使用Element UI时,要实现在一个表格组件(el-table)里的输入组件(el-input)中按下回车,使光标向右移动。
<template>
<el-table :data="tableData" border style="width: 100%">
<el-table-column
v-for="column in columns"
:key="column.prop"
:prop="column.prop"
:label="column.label"
>
<template #default="{ row, $index, column }">
<el-input
v-model="row[column.property]"
@keyup="onKeyup($index, column.property, $event)"
:ref="`input-${$index}-${column.property}`"
>el-input>
template>
el-table-column>
el-table>
template>
<script>
export default {
name: 'TableData',
data() {
return {
columns: [
{ label: '日期', prop: 'date' },
{ label: '姓名', prop: 'name' },
{ label: '地址', prop: 'address' }
],
tableData: [
{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
},
{
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
},
{
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
},
{
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
}
]
}
},
methods: {
onKeyup(rowIndex, columnProp, event) {
if (event.key !== 'Enter') {
return
}
// 当前列在columns数组中的索引
const columnIndex = this.columns.findIndex((c) => c.prop === columnProp)
// 计算下一个输入框的位置,如果是当前行的最后一个输入框则移到下一行的第一个输入框
const nextColumnIndex = (columnIndex + 1) % this.columns.length
const nextRowIndex = columnIndex === this.columns.length - 1 ? rowIndex + 1 : rowIndex
const nextInputRef = `input-${nextRowIndex}-${this.columns[nextColumnIndex].prop}`
this.$nextTick(() => {
if (this.$refs[nextInputRef]) {
this.$refs[nextInputRef][0].focus()
}
})
}
}
}
script>
<script setup>
import { nextTick, ref } from 'vue'
const columns = [
{ label: '日期', prop: 'date' },
{ label: '姓名', prop: 'name' },
{ label: '地址', prop: 'address' }
]
const tableData = [
{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
},
{
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
},
{
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
},
{
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
}
]
const refList = ref({})
const setRef = (el, key) => {
refList.value[key] = el
}
function onKeyup(rowIndex, columnProp, event) {
if (event.key !== 'Enter') {
return
}
// 当前列在columns数组中的索引
const columnIndex = this.columns.findIndex((c) => c.prop === columnProp)
// 计算下一个输入框的位置,如果是当前行的最后一个输入框则移到下一行的第一个输入框
const nextColumnIndex = (columnIndex + 1) % this.columns.length
const nextRowIndex = columnIndex === this.columns.length - 1 ? rowIndex + 1 : rowIndex
const nextInputRef = `input-${nextRowIndex}-${this.columns[nextColumnIndex].prop}`
nextTick(() => {
if (refList.value[nextInputRef]) {
refList.value[nextInputRef].focus()
}
})
}
script>
<template>
<el-table :data="tableData" border style="width: 100%">
<el-table-column
v-for="column in columns"
:key="column.prop"
:prop="column.prop"
:label="column.label"
>
<template #default="{ row, $index, column }">
<el-input
v-model="row[column.property]"
@keyup="onKeyup($index, column.property, $event)"
:ref="(el) => setRef(el, `input-${$index}-${column.property}`)"
/>
template>
el-table-column>
el-table>
template>
设置一个
el-input
的key事件监听器,并在用户按下回车键时使焦点向右移动到下一个输入组件。注意每行的最后一个输入组件移动焦点时要考虑是否是最后一个列,如果是,则需要移到下一行的第一个输入框。最后一行最后一个输入框按下回车后,目前的代码没有处理焦点的移动,可以根据需求添加逻辑处理,比如回到第一行第一列的输入组件的焦点。