vue3输入框生成的时候自动获取焦点

前言

当我们在做vue3的项目的时候,在对一些信息的修改的时候,需要双击或者点击按钮来进行操作,让数据变成输入框来进行修改数据,当输入框失去焦点的时候就进行保存,然而不方便的是,输入框出现的时候不能获取焦点导致用户的体验不好。

创建实例演示(创建文件,可忽略)

首先我们需要一个vue3的项目,如何创建一个vue3的项目,新建一个空的文件夹,cmd打开,输入

1. vue create 项目的名称
举例:vue create demo
我们选择自定义,即
2. Manually select features
回车,按需引入自己需要的,按空格即代表选中
3. 举例:
>(*) Babel(*) TypeScript( ) Progressive Web App (PWA) Support(*) Router(*) Vuex(*) CSS Pre-processors(*) Linter / Formatter( ) Unit Testing( ) E2E Testing
回车
4. 选择要用来启动项目的 Vue.js版本(使用箭头键),选择3.x
5. 使用类样式组件语法? 输入N
6. 将 Babel 与 TypeScript 一起使用(现代模式、自动检测的 polyfills、转译 JSX 需要)?输入Y
7. 路由器使用history模式?选择N (这个决定你编译出来的地址是否含有 /#/ 的字样)
8. 选择一个 CSS 预处理器 这里按自己的需求来,这里我选择Sass/SCSS (with dart-sass)
9. 选择一个 linter /格式化程序配置 选择ESLint + Standard config
10. Pick additional lint features 选择Lint on save
11. 您更喜欢将 Babel、ESLint 等的配置放在何处? 选择In dedicated config files,这样好处理
12. 将此保存为将来项目的预设?这里我选择N,看个人的需求了

定义一些简单的页面,我们用到了bootstrap的一些样式需要在public文件夹的index.html添加外部样式的引入<link href=“https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css” rel=“stylesheet”>书写在title标签下即可,在HomeView页面文件书写简单的代码

<template><div class="container"><ul class="list-group"><template v-for="(i, index) in list" :key="index"><li class="list-group-item d-flex justify-content-between" v-if="!i.checked"><div class="form-group form-check mb-0"><input type="checkbox" class="form-check-input" /><label v-if="!i.isEdit" class="form-check-label" @dblclick="showEdit(i, index)"> {{ i.name }} </label><label v-else class="form-check-label" :for="'i-' + index"><!--  --><input type="text" v-model="editValue" @blur="changeEdit" ref="myInput"/></label></div><button type="button" class="close" aria-label="Close" @click="remove(index)"><span aria-hidden="true">&times;</span></button></li></template></ul></div>
</template>

JS代码如下

<script lang="ts">
import { defineComponent, reactive, toRefs, ref } from 'vue'export default defineComponent({name: 'HomeView',setup() {// 元素节点const myInput = ref(null)// 编辑的索引let editIndex = 0// 是否获取焦点const open = 0// 数据const state = reactive({value: '',editValue: '',list: [{name: '1',checked: false,isEdit: false},{name: '2',checked: false,isEdit: false},{name: '3',checked: false,isEdit: false}]})// 双击修改const showEdit = (item, index) => {if (open == 0) {open = 1editIndex = indexitem.isEdit = truestate.editValue = item.name}}// 失去焦点const changeEdit = () => {state.list[editIndex] = {name: state.editValue,checked: false,isEdit: false}open = 0editIndex = 0}// 移除const remove = (index) => {state.list.splice(index, 1)}return {...toRefs(state),showEdit,changeEdit,remove,myInput}}
})
</script>

基础页面搭建好了之后,在终端输入

npm run serve

将项目跑起来,我们会看到三条任务

双击就可以编辑,点击叉号可以删除,复选框和添加的未加上

解决方法

当我们双击进行编辑的时候,会发现输入框不能获取焦点,用户的输入十分不方便,而且当我们想失去焦点的时候,也不许去点击输入框再失去焦点才能取消修改,十分的麻烦。

1、方法一

我们可以添加异步的手法让输入框出现之后再执行获取焦点的手法来解决,具体的解决代码如下

    // 双击修改const showEdit = (item, index) => {if (open == 0) {setTimeout(() => {myInput.value[0].focus()})open = 1editIndex = indexitem.isEdit = truestate.editValue = item.name}}

通过插入一个延时器来解决问题

2、方法二

熟悉vue2的朋友应该知道$nextTick就可以解决,但在这里vue3需要配合监听使用,还需要ref来选择我们需要操作的元素对象,查阅官网的ref使用方法,和vue2不一样,在vue2中,我们需要给我们需要的元素节点打上ref标签,读取直接使用this.$refs来操作,演示如下

template:<button ref="btn"></button>
methods:this.$refs.btn

vue3中的使用读取:

<template><div ref="box">div</div>
</template><script>
// 引入
import { onMounted, ref } from 'vue';
export default {name: 'App',setup() {let box = ref(null);// onMounted() 中的行为会在声明周期 mounted 中执行。onMounted(() => {// 在这里就可以读取到我们需要的元素节点console.log('box.value', box.value);})return {box};}
}
</script>

但是,我们的input框是根据state.list每一项的isEdit决定的,也就是说onMounted执行的时候,我们的输入框一直是未打开的,只有当我们双击的时候,才会唤醒我们的输入框,而onMounted只会在页面完全加载的时候执行一次,所以当我们双击的时候,控制台就会打印出null,此时我们是获取不到我们需要的元素节点,也就是代码

// 使用之前记得引入onMounted
onMounted(() => {console.log('myInput.value', myInput.value)
})

控制台打印出的是null

这时候获取焦点

onMounted(() => {console.log('myInput.value', myInput.value)myInput.value[0].focus()
})

控制台就会报错

Uncaught TypeError: Cannot read properties of null (reading '0')at Proxy.showEdit (HomeView.vue?4752:47:1)at onDblclick (HomeView.vue?475e:67:1)at callWithErrorHandling (runtime-core.esm-bundler.js?d2dd:155:1)at callWithAsyncErrorHandling (runtime-core.esm-bundler.js?d2dd:164:1)at HTMLLabelElement.invoker (runtime-dom.esm-bundler.js?2725:369:1)

如果我们使用onUpdated,通过获取页面更新之后就去让输入框获取焦点

// 使用之前记得引入onUpdated
onUpdated(() => {console.log('myInput.value', myInput.value)
})

我们可以获取一个空数组的代理对象,而且我们失去焦点就会报错

// 代理对象
Proxy {0: input}[[Handler]]: Object[[Target]]: Array(0)[[IsRevoked]]: false

报错:

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'focus')at eval (demoView.vue?0f1f:69:1)at callWithErrorHandling (runtime-core.esm-bundler.js?d2dd:155:1)at callWithAsyncErrorHandling (runtime-core.esm-bundler.js?d2dd:164:1)at Array.hook.__weh.hook.__weh (runtime-core.esm-bundler.js?d2dd:2685:1)at flushPostFlushCbs (runtime-core.esm-bundler.js?d2dd:356:1)at flushJobs (runtime-core.esm-bundler.js?d2dd:401:1)

我们需要监视open的变化,在使用nextTick当页面完全加载的时候获取输入框的元素节点在使其获取焦点接口,因为我们之前是使用let open = 0,我们需要一定的修改,否则watchopen会报错:

No overload matches this call.The last overload gave the following error.Argument of type 'number' is not assignable to parameter of type 'object'.

引入:

import { defineComponent, reactive, toRefs, ref, nextTick, watch } from 'vue'

修改open

    // 是否获取焦点let open = ref(0)

将后面所用到的所有open改成open.value,添加监听代码:

    watch(open, (newValue, oldValue) => {if (newValue == 1) {nextTick(() => {console.log(myInput.value)console.log('--- DOM更新了 ---')myInput.value[0].focus()})}})

这时候我们就可以在每次双击改变open,即代码:open.value = 1,就会被监听到,从而使输入框获取焦点。

vue3输入框生成的时候自动获取焦点相关推荐

  1. ant-design输入框自动获取焦点

    需求: 在做移动端项目时,引入Input输入框,当使用Input输入框的时候希望自动获取焦点,这样的话在移动端输入法就会自动弹起,方便用户使用. 实现: <Inputref={function ...

  2. 进入页面输入框自动获取焦点

    自动获取焦点,输入框需要增加autofocus属性 <input type="text" autofocus>

  3. Element UI输入框focus()方法自动获取焦点失败处理方法

    Element UI输入框focus()方法自动获取焦点失败处理方法 ​ 本来想通过自定义事件触发输入框,并获取焦点,但是使用官方提示的focus()方法一直失效 后来百度了半天,终于找到一个比较好的 ...

  4. uniApp学习(8)搜索框的创建和自动获取焦点

    1.跳转到搜索页面功能 点击搜索跳转,显示热门搜索和,搜索历史 结果如下所示 1.创建搜索页search.vue 配置pages.json页面配置app-plus导航搜索页面(这个只针对h5和APP有 ...

  5. input框自动获取焦点

    fm:事情是这样的,因为是点击一个按钮 然后出现一个弹出层,弹出层有个输入框,在点击弹出层的时候就自动获取焦点,使用autofocus的话,就只会在第一次点击的获取焦点,因为model没有更新,上片段 ...

  6. js动态创建input元素并自动获取焦点

    input元素不会自动获取焦点代码如下: <div><h2>js创建input元素并自动聚焦</h2></div><script> let ...

  7. Vue 中使用 el-input 自动获取焦点和二次获取焦点问题

    最近,碰到一个问题,就是输入框旁边有一个编辑按钮,点击时,才可以对输入框进行编辑: 要实现的效果: 为了方便输入,需要自动获取焦点,所以加入了autofocus,但是发现,只有第一个并且第一次点击才起 ...

  8. tinymce自动获取焦点光标移至最后

    tinymce官方提供的API auto_focus存在一些问题,在编辑时候如果输入框有内容auto_focus方法会自动获取焦点不过光标在最前面 我们可以调用这个函数去解决这个问题 //获取焦点光标 ...

  9. vue input自动获取焦点的方法

    在移动端输入框想自动获取焦点(自动弹出输入法) 我是在 uitls 文件下面 index.js 注册全局的指令 import Vue from 'vue' // 注册一个全局自定义指令 v-focus ...

最新文章

  1. Java并发,volatile+不可变容器对象能保证线程安全么?!
  2. ASP实现单条件和多条件组合查询的实例
  3. boost::mp11::mp_find相关用法的测试程序
  4. Visual Studio 添加 自定义 路径宏
  5. 信息学奥赛一本通 2025:【例4.11】体操队
  6. 本地添加Maven管理
  7. [C#.NET通用权限管里系统组件]对资源权限、列表型、记录级权限、数据集权限的实现参考...
  8. 前端的深拷贝和浅拷贝_javascript中的深拷贝和浅拷贝?
  9. 【零基础学Java】—对象的内存图(八)
  10. 查看windows系统信息
  11. 7-2 换硬币 (20 分)
  12. cf319.B. Modulo Sum(dp 鸽巢原理 同余模)
  13. 驱动精灵安装的流氓软件如何卸载、及删除驱动精灵
  14. PWM占空比和电机转速有什么线性关系
  15. uefi启动服务器系统安装win7系统教程,uefi引导gpt安装win7教程
  16. 机器学习中的概率分布
  17. 免费在线pdf转word
  18. MDT 2013 从入门到精通之Office 2013应答文件生成
  19. JTextArea用法
  20. 最赏识王小川的,还是马化腾

热门文章

  1. Java字符缓冲区BufferedWriter和BufferedReader详解
  2. jQuery获取动态id的办法
  3. E2E E2E测试是什么+ E2E通信是什么 +E2E模块实现的功能
  4. 2021年ACM竞赛班训练(六)题解
  5. windows7与linux共存,windows7和linux可以并存吗?
  6. 学习篇-springboot-系统初始化器
  7. Django-配置媒体资源-设置路由分发规则(下)
  8. Linux中配置NFS共享资源
  9. hwc_layer_1
  10. Mac Idea使用技巧