【问题标题】:vuejs: Trying to focus the input using v-el directivevuejs:尝试使用 v-el 指令集中输入
【发布时间】:2015-06-16 06:43:09
【问题描述】:

我正在创建一个向导登录表单,首先输入手机号码,然后 接下来输入密码。

我正在尝试使用

来集中密码输入
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();
    }
}

});

【问题讨论】:

    标签: vue.js


    【解决方案1】:

    您的密码输入位于 v-if 块中,只有在您将 flow.password 设置为 true 时才会呈现该块;但是 Vue 使用异步渲染,所以 v-if 块不会立即渲染。您可以使用Vue.nextTick 等到它完成:

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

    阅读more details 的异步渲染指南。

    【讨论】:

    • 我将添加这个,如果您在另一个方法中引用您的 el this,则 Vue.nextTick 存在于该方法中。这不是很清楚。
    【解决方案2】:

    在 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/

    【讨论】:

    • 这是唯一适用于 v-for 循环中的输入字段的解决方案。
    • 我不得不修改此解决方案以删除更新:部分。我有两个字段,用户名和密码,并用 v-focus 标记了用户名。输入密码时,焦点会跳回到每个字符的用户名。我可以想象,也许通过删除更新功能,我会错过一些应该触发关注用户名的事件,但到目前为止还没有遇到。
    • 一个简洁而有效的答案,如果可以的话,我会给你 2 票。谢谢。
    • this page 记录的示例。
    【解决方案3】:

    如果您使用的是 vuejs 2,您应该阅读以下内容:

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

    --

    在这种情况下,在您的模板中:

    使用ref="passwordInput" 代替v-el="passwordInput"

    在你的方法中:

    this.$refs.passwordInput.focus()
    

    希望对你有帮助!

    【讨论】:

    • 我得到:Uncaught TypeError: Cannot read property 'passwordInput' of undefined
    【解决方案4】:

    很高兴这对你们中的一些人有用。 我不知道为什么,但是在尝试了已接受答案的所有可能变化之后,我在使用 v-repeat 时无法获得 $$.ref 属性。 我只能像这样访问新创建的 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 之外调用的,所以即使是建议的答案 here 也无济于事

    不确定这样做是否有问题,但它有效,我累了。

    【讨论】:

      【解决方案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();
        

        希望对你有帮助。

        【讨论】:

        • 我得到:未捕获的类型错误:无法读取未定义的属性“txtName”。这在“created”方法中。
        【解决方案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>
        

        像这样。

        【讨论】:

          猜你喜欢
          • 2015-10-29
          • 1970-01-01
          • 2018-08-13
          • 2019-06-07
          • 1970-01-01
          • 1970-01-01
          • 2018-04-11
          • 1970-01-01
          • 2018-06-13
          相关资源
          最近更新 更多