(三十四)Vue之新生命周期钩子nextTick

文章讲述了在Vue中处理元素焦点的一个常见问题,即在数据更新后,由于DOM未立即更新导致无法正确获取焦点。作者提出了一个普通实现,但在点击编辑按钮时,文本框不会自动获取焦点。问题的关键在于Vue的数据绑定是异步的。为了解决这个问题,文章介绍了使用`this.$nextTick`方法来确保在DOM更新之后再执行获取焦点的操作,避免了不必要的定时器使用,优化了代码逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上一篇:(三十三)Vue之消息订阅与发布

下一篇:(三十五)Vue之过渡与动画

首先先看这一个需求,给每个任务项新增一个编辑按钮
请添加图片描述
当编辑按钮点击时,任务项就会变成文本框,并且自动获取焦点
在这里插入图片描述

普通实现的一个问题

首先在Item组件定义元素

<li>
    <label>
      <input type="checkbox" :checked="todo.done" @change="handleCheck(todo.id)"/>
      <span v-show="!todo.isEdit">{{todo.title}}</span>
      <input v-show="todo.isEdit" type="text" :value="todo.title" @blur="handleBlur(todo,$event)" ref="inputTitle">
    </label>
    <button class="btn btn-danger" @click="handleDelete(todo.id)">删除</button>
    <button v-show="!todo.isEdit" class="btn btn-edit" @click="handleEdit(todo)">编辑</button>
</li>

回调实现

    handleEdit(todo){
      //查看每项是否有编辑标志属性,没有则加一个isEdit编辑属性
      if (todo.isEdit !== undefined){//todo.hasOwnProperty('isEdit')
        todo.isEdit = true
      }else {
        this.$set(todo,'isEdit',true)
      }
      this.$refs.inputTitle.focus()
    },
    //当文本框失去焦点
    handleBlur(todo,e){
      todo.isEdit = false
      if (!e.target.value) return alert('输入不能为空')
      this.$bus.$emit('updateTodo',todo.id,e.target.value)
    }

App组件定义回调及利用全局事件总线绑定
回调

	updateTodo(id,title){
      this.todos.forEach((todo)=>{
        if (todo.id === id) todo.title = title
      })
    }

在mounted钩子绑定事件

this.$bus.$on('updateTodo',this.updateTodo)

在beforeDestroy解绑事件

this.$bus.$off('updateTodo')

效果:当我们点击编辑按钮时,会变成文本框,但是不会自动获取焦点原因是,vue在执行this.$set(todo,'isEdit',true)这行代码,vue不会去重新解析模板,它会继续往下走,直到走完这个回调,当走到获取焦点的代码的时候,文本框还没有到页面中,这时一个顺序问题

解决问题

上面说到的问题是一个顺序问题,最简单的方法,把获取焦点的代码变成异步操作即可

	setTimeout(()=>{
        this.$refs.inputTitle.focus()
      },200)

nextTick

要是很多次出现这个问题,就需要开很多定时器,我们知道,开定时器是有代价的,所以官方设计了一个API,用于异步更新操作

语法:this.$nextTick(回调函数)

作用:在下一次 DOM 更新结束后执行其指定的回调。

使用时机:当改变数据后,要基于更新后的新DOM进行某些操作时,要在nextTick所指定的回调函数中执行。

所以,获取焦点的操作就可以使用nextTick进行操作

	this.$nextTick(function () {
        this.$refs.inputTitle.focus()
      })
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

忆亦何为

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值