vue/iview的table单元格可编辑,可上下键切换,小键盘enter可选中下一个 您所在的位置:网站首页 表格怎样用键盘切换进入下一个格子 vue/iview的table单元格可编辑,可上下键切换,小键盘enter可选中下一个

vue/iview的table单元格可编辑,可上下键切换,小键盘enter可选中下一个

2024-07-05 19:18| 来源: 网络整理| 查看: 265

在开发过程中,前后至今遇到好几次的编辑输入框编辑情况,4.24之前的版本,虽然改进好几次操作,但是都是用render函数实现,发现有时并不是很好操作,而且隐藏好几个bug,今天(2019-7-19)发布一个新版,目前无发现bug,而且监听键盘更灵活。废话不多说,上代码

  2019-04-24版本

因为需要多列可编辑表格,直接用render函数,isNum代表这个数是否需要只允许输入小数点

有一点要特别注意,表格展示的数据用tableData,然后深拷贝一组数据,copyTableData,不然实际过程中发现赋值的时候,容易失去焦点

columns的代码如下:

storeColumns: [ {title: '序号', type: 'index', align: 'center', fixed: 'left', width: 60}, {title: '供应商', key: 'VenderName', align: 'center', fixed: 'left', width: 180}, {title: '商品名称', key: 'GoodsName', align: 'center', fixed: 'left', width: 180}, {title: '商品条码', key: 'BarCode', align: 'center', width: 180}, {title: '品类', key: 'CategoryName', align: 'center', width: 180}, {title: '单位/规格', key: 'SpecUnit', align: 'center', width: 180}, {title: '保质期', key: 'ShelfLife', align: 'center', width: 180}, {title: '销售量', key: 'Qty', align: 'center', width: 180}, {title: '同期总销售额', key: 'SaleValue', align: 'center', width: 180}, {title: '同期毛利额', key: 'GrossProfit', align: 'center', width: 180}, {title: '同期毛利率(%)', key: 'RateOfMargin', align: 'center', width: 180}, {title: '昨日库存总量', key: 'CloseQty', align: 'center', width: 180}, {title: '建议补货量', key: 'SRQ', align: 'center', width: 180}, {title: '订货周期', key: 'OrderCycle', align: 'center', width: 180}, {title: '门店订货量', key: 'OrderQtyShop', align: 'center', width: 180, render: (h, params) => {return this.renderInput(h, params, 'OrderQtyShop', 1)}}, {title: '预计售完时间', key: 'SellOutDate', align: 'center', width: 180, render: (h, params) => {return this.renderInput(h, params, 'SellOutDate')}}, {title: '陈列位置', key: 'POD', align: 'center', width: 180, render: (h, params) => {return this.renderInput(h, params, 'POD')}}, {title: '进价', key: 'CostPrice', align: 'center', width: 180}, {title: '平均售价', key: 'AvgPrice', align: 'center', width: 180}, {title: '计划促销价', key: 'PlanPromPrice', align: 'center', width: 180, render: (h, params) => {return this.renderInput(h, params, 'PlanPromPrice', 1)}}, {title: '备注', key: 'Notes', align: 'center', width: 280, render: (h, params) => {return this.renderInput(h, params, 'Notes')}} ],

 renderInput的代码如下,如果有一些功能不需要刻意自己删除,代码有一点乱,可以取自己需求的

renderInput (h, params, values, isNum) { // 设置一个class,方便待会进行操作dom let ref = values + params.row._index + 'n' return h('Input', { class: [ `${ref}` ], props: { // 给予初始值 value: params.row[values], }, on: { 'on-blur': (e) => { // 失去焦点时赋值 this.$set(this.copyTableData[params.row._index], values, this.changeValue) }, 'on-focus': () =>{ // 获取焦点时,给changeValue中间变量赋值,且选中当前值 this.changeValue = this.copyTableData[params.row._index][values] setTimeout(()=> { document.getElementsByClassName(`${ref}`)[0].children[1].select() }) } }, nativeOn: { keydown: (event) => { // 监听键盘变化,input上下框可以通过上下键切换 if (event.keyCode === 38) { if (this.cando) { return } this.cando = true setTimeout(() => { this.cando = false let name = values + (params.row._index - 1) + 'n' document.getElementsByClassName(`${name}`)[0].children[1].focus() }, 50) } if (event.keyCode === 40) { if (this.cando) { return } this.cando = true setTimeout(() => { this.cando = false let name = values + (params.row._index + 1) + 'n' document.getElementsByClassName(`${name}`)[0].children[1].focus() }, 50) } }, input: (e) => { // 项目要求只允许输入三位小数点,直接操作dom赋值 let val = e.target.value if (isNum) { val = val.replace(/[^\d.]/g, ""); //清除“数字”和“.”以外的字符 val = val.replace(/\.{2,}/g, "."); //只保留第一个. 清除多余的 val = val.replace(".", "$#$").replace(/\./g, "").replace("$#$", "."); val = val.replace(/^(\-)*(\d+)\.(\d\d\d).*$/, '$1$2.$3'); console.log(val) setTimeout(() =>{ document.getElementsByClassName(`${ref}`)[0].children[1].value = val }, 2) this.changeValue = val } else { this.changeValue = val } } }, key: ref }) }, 2019-7-19效果如图

 1.HTML主要用slot进行操作,需要添加一个class,方便后续dom操作 // 主要利用iview 的slot进行操作 // keyup.native 监听按钮事件 // inputName 监听输入事件,主要限制数字等输入 {{row.danwei}} {{row.danwei}} kg {{row.danwei}} 2.表头和表格数据 // 表头数据格式定义,咳咳,忽略拼音的key tableColumns: [ { type: 'selection', align: 'center', width: 50, fixed: 'left' }, { title: '序号', type: 'index', width: 80, align: 'center', fixed: 'left' }, { title: '编码', key: 'num', align: 'center', fixed: 'left', width: 100 }, { title: '品名', key: 'pinming', align: 'center', fixed: 'left', width: 100 }, { title: '单位', key: 'danwei', align: 'center', width: 80 }, { title: '单价', key: 'danjia', width: 100, slot: 'danjia', renderHeader: (h, params) => this.renderHeader(h, params, '单价(元)', 'danjia') }, { title: '数量', key: 'shuliang', slot: 'shuliang', width: 100, align: 'center' }, { title: '金额(元)', key: 'jine', align: 'center', width: 100, renderHeader: (h, params) => this.renderHeader(h, params, '金额(元)', 'jine') }, { title: '赠送数量', key: 'zengsong', slot: 'zengsong', width: 100, align: 'center' }, { title: '计数', key: 'jishu', align: 'center', width: 100, slot: 'jishu', renderHeader: (h, params) => this.renderHeader(h, params, '计数', 'jishu') }, { title: '计重', key: 'jizhong', align: 'center', width: 100, slot: 'jizhong', renderHeader: (h, params) => this.renderHeader(h, params, '计重', 'jizhong') }, { title: '件数', key: 'jianshu', align: 'center', width: 100, slot: 'jianshu', renderHeader: (h, params) => this.renderHeader(h, params, '件数', 'jianshu') }, { title: '原产地', key: 'yuanchandi', align: 'center', width: 150, slot: 'yuanchandi' }, { title: '生产日期', key: 'shengcanriqi', align: 'center', width: 180, slot: 'shengcanriqi' }, { title: '保质期', key: 'baozhiqi', align: 'center', width: 300, slot: 'baozhiqi' } ], // 当然是假数据,哈哈哈,后端数据没来,key全部用拼音代替 tableData: [ {danwei: '头', num: 1, pinming: '品名1', danjia: 2, shuliang: 2, jine: 2, jishu: 2, jizhong: 3, jianshu: 5}, {danwei: '个', num: 1, pinming: '品名2', danjia: 2, shuliang: 2, jine: 2, jishu: 2, jizhong: 3, jianshu: 5}, {danwei: '个', num: 1, pinming: '品名2', danjia: 2, shuliang: 2, jine: 2, jishu: 2, jizhong: 3, jianshu: 5}, {danwei: '个', num: 1, pinming: '品名2', danjia: 2, shuliang: 2, jine: 2, jishu: 2, jizhong: 3, jianshu: 5}, {danwei: 'kg', num: 1, pinming: '品名3', danjia: 2, shuliang: 2, jine: 2, jishu: 2, jizhong: 3, jianshu: 5} ], 3. methods方法的定义,直接操作dom,小键盘enter键向右既下一个,注意需要按顺序写一个对象 // 表头方法定义,由于个别列需要进行输入合计 renderHeader (h, params, name, key) { return h('div', [ h('div', name), h('div', { style: { 'text-align': 'right' } }, this.addNum[key]) ]) }, // 按键切换 handleKeyup (event, index, key) { // 向上键 if (event.keyCode === 38) { // 获取到所有class为[key]的dom列表 let doms = document.getElementsByClassName(key) if (!index) { index = this.copyTableData.length } // 选中类表中第index个,向上故而减1,dom里头包含的input,获取焦点以及选中input里的内容 let dom = doms[index - 1].getElementsByTagName('input')[0] dom.focus() dom.select() } // 向下键 if (event.keyCode === 40) { let doms = document.getElementsByClassName(key) if (+index === this.copyTableData.length - 1) { index = -1 } let dom = doms[index + 1].getElementsByTagName('input')[0] dom.focus() dom.select() } // 小键盘回车键 if (event.keyCode === 13) { // 小键盘回车因为需要根据class判断下一个,故而有input输入框的全部需要在这按顺序声明 let keyName = ['danjia', 'shuliang', 'zengsong', 'jishu', 'jizhong', 'jianshu', 'yuanchandi', 'shengcanriqi', 'baozhiqi'] let num = 0 if (key === keyName[keyName.length - 1]) { if (index === this.copyTableData.length - 1) { index = 0 } else { ++index } } else { keyName.map((v, i) => { if (v === key) { num = i + 1 } }) } let doms = document.getElementsByClassName(keyName[num]) let dom = doms[index].getElementsByTagName('input')[0] dom.focus() dom.select() } }, // 输入赋值,记得不直接给tableData赋值,而是深度拷贝一个,不然从新渲染时会失去焦点 inputName (value, row, index, key) { let ret = this.regular(value) let dom = document.getElementsByClassName(key) setTimeout(() => { dom[index].children[1].value = ret }) this.copyTableData[index][key] = value }, // 正则验证,限定输入数字,到时可根据参数选择要不要验证,这里自己看是否需要 regular (value) { value = value.replace(/[^\d.]/g, '') // 清除"数字"和"."以外的字符 value = value.replace(/[^\d.]/g, '') // 清除"数字"和"."以外的字符 value = value.replace(/^\./g, '') // 验证第一个字符是数字而不是 value = value.replace(/\.{2,}/g, '.') // 只保留第一个. 清除多余的 value = value.replace('.', '$#$').replace(/\./g, '').replace('$#$', '.') console.log('value2:' + value) value = value.replace(/^(-)*(\d+)\.(\d{3}).*$/, '$1$2.$3') // 只能输入两个小数 return value } 4.computed计算属性监听头部数字变化 computed: { addNum () { let nums = { jine: 0, jishu: 0, jizhong: 0, jianshu: 0 } this.copyTableData.map(v => { nums.jine += +v.jine nums.jishu += +v.jishu nums.jizhong += +v.jizhong nums.jianshu += +v.jianshu }) return nums } },

 



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有