【Vue】输入框状态切换&自动获取输入框焦点の实现
设置一个0ms的定时器,当浏览器执行到定时器时,会将定时器内部的函数放入延迟队列中,当定时器的等待事件结束后,会将函数放入消息队列的末尾,消息队列的执行按照先进先出原则,当前面的任务执行完成后,浏览器会自动执行。通俗的理解是:等组件的 DOM 更新完成之后,再执行 cb 回调函数。按钮展示输入框,并自动获取对话框焦点,失去焦点时展示。,实现点击按钮展示输入框,给输入框绑定失去焦点事件。时,页面已经
场景:点击button
按钮展示输入框,并自动获取对话框焦点,失去焦点时展示button
按钮
实现:
-
点击
button
按钮展示输入框,失去焦点时展示button
按钮-
在data中定义
visibility
,确定输入框的展示状态,默认为false
-
定义
changeVisibility
方法,并给button
绑定点击事件@click="changeVisibility"
,实现点击按钮展示输入框,给输入框绑定失去焦点事件@blur="changeVisibility"
-
定义
input
和button
元素,绑定条件渲染指令v-if
,当visibility
为false
时展示按钮,反之展示输入框 -
代码实现:
<template> <div> <label for="input"> <input type="text" ref="inputRef" v-if="visibility" @blur="changeVisibility"> <button @click="changeVisibility" v-else>展示文本框</button> </label> </div> </template> <script> export default { data() { return { visibility: false } }, methods: { changeVisibility() { this.visibility = !this.visibility // 切换 visibility,控制输入框的显示状态 } } } </script>
-
-
自动获取对话框焦点
文本框的焦点可以通过
.focus()
获取,因此我们可以通过this.$refs.inputRef.focus()
获取到显示的输入框的焦点(inputRef
是创建文本框时添加的ref
引用)。但是方法定义在组件渲染之前,因此直接在方法中添加会导致控制台报错:Error in v-on handler: "TypeError: Cannot read properties of undefined (reading 'focus')"
。这是由于浏览器执行到this.$refs.inputRef.focus()
时,
input
元素还没有被渲染到页面上,此时DOM中还不存在指定的input
元素。为了避免这种情况,可以使用以下三种方法推迟焦点的获取-
设置定时器, 推迟焦点的获取
setTimeout(()=> { this.$refs.inputRef.focus() },0)
设置一个0ms的定时器,当浏览器执行到定时器时,会将定时器内部的函数放入延迟队列中,当定时器的等待事件结束后,会将函数放入消息队列的末尾,消息队列的执行按照先进先出原则,当前面的任务执行完成后,浏览器会自动执行
this.$refs.inputRef.focus()
实现焦点的获取 -
使用
$nextTick
方法, 将获取焦点推迟到下一个 DOM 更新周期this.$nextTick(()=> { this.$refs.inputRef.focus() })
组件的
$nextTick(cb)
方法,会把 cb 回调推迟到下一个 DOM 更新周期之后执行。通俗的理解是:等组件的 DOM 更新完成之后,再执行 cb 回调函数。从而能保证 cb 回调函数可以操作到最新的 DOM 元素。
-
将获取焦点放到
updated
生命周期中执行(不推荐)
使用这个方法时,需要加上if
判断,否则每一次this.visibility
发生变化时,都会执行一次更新,增加服务器的负担updated() { if (this.visibility){ this.$refs.inputRef.focus() } }
当组件处于
updated
时,页面已经根据最新的数据渲染完成了,此时我们执行this.$refs.inputRef.focus()
就可以正常获取输入框的焦点
-
更多推荐
所有评论(0)