Vue表单回车事件下一个input获取焦点

动态生成的一组input,触发enter事件后怎么focus下一个input

<li class="border-none" v-for="(item,index) in prcHdAreaList" :key="item.pmcKeyVal">
    <input
         :ref="item.pmcKeyVal"
         v-focus-next-on-enter="'item.pmcKeyVal'" 
         name="item.phaRate" class="cus_input" 
         v-model.trim="item.phaRate" type="number"/>
</li>

Vue.directive('focusNextOnEnter', {
      bind: function(el, {value}, vnode) {
        el.addEventListener('keyup', (ev) => {
          if (ev.keyCode === 13) {
            let nextInput = vnode.context.$refs[value]
            if (nextInput && typeof nextInput.focus === 'function') {
              nextInput.focus()
              nextInput.select()
            }
          }
        })
     }
})
阅读 13.5k
4 个回答
经过我几个小时的尝试,使用自定义指令实现了该需求,没有使用任何原生的DOM操作和插件,直接使用了vue提供的方法实现的。

具体代码(直接复制粘贴便可看到效果,重要地方都做了注释):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<div id="app">
    <ul>
      <li v-for="(item,index) in inputs">
        <input type="text" v-model="item.val" v-focus="focusIndex === index"  @keyup.enter="nextFocus(index)">
      </li>
    </ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
  // 注册一个全局自定义指令 `v-focus`
  Vue.directive('focus', {
    // 当被绑定的元素插入到 DOM 中时……
    inserted: function (el,obj) {  //这是需要页面刚加载就能进行聚焦操作使用的钩子函数,可以省略的,视具体需求而定
      //console.log(obj);
      if(obj.value) { //对值进行判断
        // 聚焦元素
        el.focus()        
      }
    },
    // 当指令所在组件的 VNode 及其子 VNode 全部更新后调用
    componentUpdated: function(el,obj) {  //这是每当绑定的值发生改变时触发的钩子函数
      //console.log(obj);  //可以打印看一下
      if(obj.value) {
        el.focus()        
      }
    }
  })
  new Vue({
      el: "#app",
      data() {
        return {
          focusIndex: 0, //用来存放下一个应该聚焦的index值
          inputs: [{
            val: 1
          },{
            val: 2
          },{
            val: 3
          },{
            val: 4
          }]
        }
      },
      methods: {
        nextFocus(index) {
          return this.focusIndex = index + 1;
        }
      }
  });
</script>
</body>
</html>

希望我的回答对你有所帮助!^_^^_^ 不足之处,欢迎批评指正!

直接上代码吧- 动态数据,动态获取,动态焦点--ohye
图片描述

<template>
  <ul>
    <li v-for="product in products">
      {{ product.title }} - {{ product.price | currency }}
      <br>
      <input 
      type="text" 
      :value='product.title'
      :ref='"nnnn"+product.id'
      @keyup.enter="(e)=>doneEdit('nnnn'+product.id)"
      ></input>
      <button
        :disabled="!product.inventory"
        @click="addProductToCart(product)">
        Add to cart
      </button>
    </li>
  </ul>
</template>

<script>
const allproducts = [
  {"id": 1, "title": "iPad 4 Mini111", "price": 500.01, "inventory": 2},
  {"id": 2, "title": "H&M T-Shirt White", "price": 10.99, "inventory": 10},
  {"id": 3, "title": "Charli XCX - Sucker CD", "price": 19.99, "inventory": 5}
]
import { mapGetters, mapActions } from 'vuex'

export default {
  computed:{ 
    products:function(){ return allproducts}
  },
  methods:{ 
    doneEdit:function(refid){
    let dom=this.$refs[refid][0];
    dom.parentNode.nextElementSibling 
    && dom.parentNode.nextElementSibling.childNodes[3].focus()
    },
    ...mapActions([
    'addProductToCart',
  ])},
  beforeCreate(){
    console.log('生命周期');
  },
  created () {
    this.$store.dispatch('getAllProducts')
  }
}
</script>

根据@luozz的提示精简了下代码

<li class="border-none" v-for="(item,index) in prcHdAreaList" :key="item.pmcKeyVal">
    <input
         v-validate="'required'"
         @keyup.enter="nextInput('hdArea',index)"
         :class="{'input': true, 'is-danger': errors.has('item.phaRate'), 'hdArea': true }" 
         name="item.phaRate" class="cus_input" 
         v-model.trim="item.phaRate" type="number"/>
</li>
nextInput: function(name,index){
    var inputs = document.getElementsByClassName(name);
    inputs[index + 1].focus();
    inputs[index + 1].select()
},
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
  <div class="wrap">
    <input type="text" @keydown.enter="fun()">
    <input type="text" @keydown.enter="fun()">
    <input type="text" @keydown.enter="fun()">
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue"></script>
  <script type="text/javascript">
    var vm = new Vue({
      el: ".wrap",
      methods: {
        fun() {
          const DOM = event.target
          const nextDOM = DOM.nextElementSibling
          nextDOM.focus()
        }
      }        
    })
  </script>
  </div>
</body>
</html>

如上代码所示,nextElementSibling获取下一个兄弟节点,再focus()获取焦点即可

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题