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

上一篇:(三十三)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()
      })

猜你喜欢

转载自blog.csdn.net/weixin_45832694/article/details/129073632
今日推荐