Vuejs: попытка фокусировки ввода с использованием директивы v-el

Я создаю регистрационную форму мастера, где сначала вводится номер мобильного телефона и пароль вводится далее.

Здесь я пытаюсь сфокусировать ввод пароля с помощью

this.$$.passwordInput.focus()

однако, если я получаю ошибку, приведенную ниже

Uncaught TypeError: Cannot read property 'focus' of undefined

Полный код ниже

index.html

<div id="login">
  <div v-if="flow.mobile">
    <form v-on="submit: checkmobile">
        <p>
          Mobile Number<br>
          <input type="text" v-model="mobile_number" v-el="mobileNumber">
        </p>
    </form>
  </div>
  <div v-if="flow.password">
    <form v-on="submit: checkpassword">
        <p>
          Password<br>
          <input type="password" v-model="password" v-el="passwordInput">
        </p>
    </form>
  </div>

script.js

var demo = new Vue({
el: '#login',
data: {
    flow: {
        mobile: true,
        password: false
    }
},
methods: {
    checkmobile: function(e) {
        e.preventDefault();
        this.flow.mobile = false;
        this.flow.password = true;
        this.$$.passwordInput.focus();
    },
    checkpassword: function(e) {
        e.preventDefault();
    }
}

});

Ответ 1

Ваш passwordInput находится внутри блока v-if, который обрабатывается только тогда, когда вы устанавливаете flow.password в true; Однако Vue использует асинхронный рендеринг, поэтому блок v-if не будет отображаться немедленно. Вы можете использовать Vue.nextTick, чтобы подождать, пока это произойдет:

this.flow.password = true;
var self = this;
Vue.nextTick(function () {
  self.$$.passwordInput.focus();
});

Прочтите руководство по асинхронной визуализации, чтобы узнать подробнее.

Ответ 2

Если вы используете vuejs 2, вы должны прочитать следующее:

https://vuejs.org/v2/guide/migration.html#v-el-and-v-ref-replaced

-

В этом случае в вашем шаблоне:

используйте ref="passwordInput" вместо v-el="passwordInput"

и в вашем методе:

this.$refs.passwordInput.focus()

Я надеюсь, что это поможет вам!

Ответ 3

В Vue.js 2.x вы можете создать собственную директиву для автоматической фокусировки поля:

Vue.directive('focus', {
    inserted: function (el) {
        el.focus();
    },
    update: function (el) {
        Vue.nextTick(function() {
              el.focus();
        })
    }
})

Затем вы можете использовать атрибут v-focus для входных данных и других элементов:

<input v-focus>

Рабочий пример: https://jsfiddle.net/LukaszWiktor/cap43pdn/

Ответ 4

Рад, что это сработало для некоторых из вас. Я понятия не имею, почему, но, пробовав все мыслимые варианты принятого ответа, я не смог получить свойство $$ ref при использовании v-repeat. Я мог получить доступ только к вновь созданным элементам dom:

new Vue({
el: '#reporting_create',
data: {
    recipients: {
        0: {
            fname: null,
            lname: null,
            email: null,
            registration: false,
            report: false
        }
    },
    curRec:1
},
methods: {
    addRecipient: function(){
        event.preventDefault();
        this.recipients.$add(
            this.curRec,
            {
                fname: null,
                lname: null,
                email: null,
                registration: false,
                report: false
            }
        );
        var num = this.curRec;
        this.$nextTick(function () {
            console.log(this._children[num].$$.rowrec);
            newSwitches.find('.switch').bootstrapSwitch();
        })

        this.curRec++;
    }
}})

HTML:

<template v-repeat="recipients">
        <div class="row" v-el="rowrec">
            <div>{{$key}}</div>
        </div>
</template>

Функция addRecipients вызывается вне v-repeat, поэтому даже предлагаемый ответ здесь не мог помочь

Не уверен, что есть проблема с этим, но он работает, и я устал.

Ответ 5

Vue.js 1 работает немного иначе.

Пример:

  <textarea v-el:model_message></textarea>

JS:

this.$els.model_message.focus();

Ответ 6

Если вы используете Vue.js 2.0, вы должны сделать следующее:

<input type="text" v-model="currentItem.name" ref="txtName">

Итак, вы можете получить доступ к этому вводу с помощью объекта $refs:

this.$refs.txtName.focus();

Надеюсь, это поможет.

Ответ 7

Документация Vue v2 использует фокус в качестве примера при написании пользовательских директив. Весь необходимый код поставляется с примером, https://vuejs.org/v2/guide/custom-directive.html. Сначала вы должны зарегистрировать директиву. Ссылка показывает, как зарегистрировать его локально на компоненте.

// Register a global custom directive called 'v-focus'
Vue.directive('focus', {
  // When the bound element is inserted into the DOM...
  inserted: function (el) {
    // Focus the element
    el.focus()
  }
})

Сделав это, вы теперь можете использовать v-focus для элемента:

<input v-focus>

Вот так.