【问题标题】:focus() not working after axios call in Vue JS在Vue JS中调用axios后focus()不起作用
【发布时间】:2021-03-01 14:39:08
【问题描述】:

我在Vue JS 中有一个form,它是通过axios 调用和axios 之后提交的,我想专注于特定的input 元素,但它无法正常工作。

这里是input

<input type="text" class="form-control mb-2" :id="'txtTazkira' + s.id" 
 @input="setTxtTazkira($event, s.id)" :value="s.tazkira" />  

表单提交时调用以下函数:

submitForm() {
  this.form.txtTazkira = this.txtTazkira
  this.form.selectedNotebook = this.selectedNotebook.id
  this.nextSlot = document.getElementById('txtTazkira' + (this.form.slotId + 1))

  axios
    .patch('/Notebook/api/slots/' + this.form.slotId, this.form)
    .then((response) => {
      this.tazkiraSaved = true
      this.fetchSlots()

      this.nextSlot.focus()
      console.log(this.nextSlot)
    })
    .catch((errors) => {
      alert('Unable to save Tazkira, There might be some issues.')
      this.tazkiraSaved = false
    })
},

可以看出,在 axios 调用之后,我有 this.nextSlot.focus() 没有将焦点设置到 input 元素。我也尝试执行以下操作但没有成功:

this.$nextTick(() => {
    this.nextSlot.focus();
});  

我还尝试了以下添加:ref="'txtTazkira' + s.id"的方法:

<input type="text" class="form-control mb-2" :id="'txtTazkira' + s.id" 
@input="setTxtTazkira($event, s.id)" :value="s.tazkira" :ref="'txtTazkira' + 
s.id">  

然后在js 中尝试了以下操作,但仍然无法正常工作:

var newSlot = 'txtTazkira' + (this.form.slotId + 1);

axios.post(.....)
{
  ...... 
  this.$nextTick(() => {
     this.$refs[newSlot].focus();
   });
}

我搜索了谷歌并找到了一些相关的讨论,但这并没有解决我的问题,因此我在这里发布了这个问题。

提前感谢任何帮助。

【问题讨论】:

  • 你试过在axios回调中定义this.nextSlot。我感觉 this.fetchSlots 触发了 DOM 更新,并且在 axios 请求之后您可能会丢失对 nextSlot 的引用。此外,正如@Asimple 所写,使用 refs 是一种更好的方法。
  • 声明var newSlot = 'txtTazkira' + (this.form.slotId + 1);时为什么要加1? (顺便说一句,在这种情况下,最好使用let 而不是var)。另一件事——如果你在focus() 之前做console.log(this.$refs)——你会得到什么?

标签: javascript vue.js axios


【解决方案1】:

在发布第一个答案之前,我开始在我的 Vue CLI 沙盒应用程序中创建一个测试组件。我没有使用它

this.$refs.input2.$el.focus();

但当我将其更改为时确实有效

this.$refs.input2.focus();

这里是测试组件:

<template>
  <div class="set-focus">
    <div class="row">
      <div class="col-md-3">
        <form @submit.prevent="submitForm">
          <div class="form-group">
            <label>Input One</label>
            <input type="text" class="form-control" ref="input1">
          </div>
          <div class="form-group">
            <label>Input Two</label>
            <input type="text" class="form-control" ref="input2">
          </div>
          <button type="submit" class="btn btn-primary">Submit</button>
        </form>
      </div>
    </div>
  </div>
</template>

<script>
  export default {
    methods: {
      submitForm() {
        console.log('submitForm')
        // Simulate API call
        setTimeout( () => {
          this.$refs.input2.focus();
        }, 2000)
      }
    }
  }
</script>

【讨论】:

    【解决方案2】:

    您的问题的解决方案是使用ref

    documentation中所述:

    尽管存在道具和事件,但有时你可能仍然 需要在 JavaScript 中直接访问子组件。实现 您可以为子组件或 HTML 分配一个参考 ID 使用 ref 属性的元素。

    看看这个简单的 sn-p:

    <html>
    <div id="app">
      <p><input v-model="myvar1" ref="myvar1"></p>
      <p><input v-model="myvar2" ref="myvar2"></p>
      <button @click="doClick(1)">Focus on 1st input</button>
      <button @click="doClick(2)">Focus on 2nd input</button>
    </div>
    
    <script src="https://unpkg.com/vue@2"></script>
    <script>
      new Vue({
        el: '#app',
        data() {
          return {
            myvar1: '',
            myvar2: '',
          }
        },
    
        methods: {
          doClick(id) {
            this.$refs['myvar'+id].focus()
          }
        }
      });
    </script>
    </html>

    顺便说一句,在您的 axios 调用中,您可以使用 finally 以便让代码执行独立于调用结果:

    .finally(() => {
      // your focus code here
    })
    

    【讨论】:

      【解决方案3】:

      您可以使用ref 而不是尝试通过 id 获取元素,这样会容易得多:

      <input
          type="text"
          class="form-control mb-2"
          ref="'txtTazkira"
          :value="s.tazkira"
          @input="setTxtTazkira($event, s.id)"
      /> 
      

      在代码中:

      this.$refs.txtTazkira.$el.focus();
      

      此外,如果您将txtTazkira ref 设置为输入数组,this.$refs.txtTazkira 也将是具有相同索引的数组。

      更多关于参考here

      【讨论】:

        猜你喜欢
        • 2014-06-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-08
        • 2017-09-10
        • 2013-07-03
        • 1970-01-01
        • 2023-03-31
        相关资源
        最近更新 更多