nextTick
1.语法: this.$nextTick(回调函数)
2.作用:在下一次DOM更新结束后执行其指定的回调
3.什么时候用:当改变数据后,要基于更新后的新DOM进行某些操作时,要在nextTick所 指定的回调函数中执行。
//例如创建一个MyItem 组件中的应用
<template>
<div>
<li>
<label>
<input
type="checkbox"
:checked="todoObj.done"
@change="handlerCheck(todoObj.id)"
/>
<span v-show="!todoObj.isEdit">{{ todoObj.title }}</span>
<input
v-show="todoObj.isEdit"
type="text"
:value="todoObj.title"
@blur="handleBlur(todoObj, $event)"
ref="inputTitle"
/>
<!-- $event表示触发的是什么事件
$event.target表示触发事件的目标dom(即整个标签)
$event.target.value表示触发事件目标中定义的值(比如上述定义的value为 todoObj.title)
-->
</label>
<button class="btn btn-danger" @click="handlerDelete(todoObj.id)">
删除
</button>
<button
v-show="!todoObj.isEdit"
class="btn btn-edit"
@click="handleEdit(todoObj)"
>
编辑
</button>
</li>
</div>
</template>
<script>
//接收和发送数据都要引入第三方库别忘了
import pubsub from "pubsub-js";
export default {
name: "MyItem",
props: ["todoObj"],
methods: {
handlerCheck(id) {
//利用全局事件总线写:
this.$bus.$emit("handlerSelected", id);
},
handlerDelete(id) {
// if (confirm("确定删除吗?")) this.$bus.$emit("todoDelete", id);
//下面用消息订阅方法示范
if (confirm("确定删除吗?")) pubsub.publish("todoDelete", id, 666);
},
handleEdit(todoObj) {
// todoObj.isEdit = true;//这样传入是不会让isEdit在vue身上有set,get函数的
// this.$set(todoObj, "isEdit", true); //这种写法效率不高因为每次调用都会执行这个代码,
//然而第一次执行时数据已经有了isEdit属性后面再编辑就不用添加了,所以最好进行判断
if (todoObj.hasOwnProperty.call(todoObj, "isEdit")) {
//借助hasOwnProperty这个API判断变量身上有没有这个属性
todoObj.isEdit = true;
} else {
console.log("只有没有isEdit属性的才会调用我");
this.$set(todoObj, "isEdit", true);
}
// this.$refs.inputTitle.focus();这种形式不行因为handleEdit整个函数执行完了才会重新解析模板
//上面这个不能用通俗的说就是页面上还没有input框(v-show),上面的代码就已经执行完了
//1定时器解决法:(没有给时间就是即刻执行,但是由于定时器还是会后面执行)
// setTimeout(() => {
// this.$refs.inputTitle.focus();
// });
//2官方API解决,用$nextTick(),它里面的命令可以再DOM完全更新之后再执行
this.$nextTick(function () {
this.$refs.inputTitle.focus();
});
},
//失去焦点回调(真正执行修改逻辑)
handleBlur(todoObj, e) {
todoObj.isEdit = false;
this.$bus.$emit("updateTodo", todoObj.id, e.target.value); //想拿到输入框里的值用$event,不然用todo.title拿的还是原来的值
},
},
};
</script>
<style scoped>
/*item*/
li {
list-style: none;
height: 36px;
line-height: 36px;
padding: 0 5px;
border-bottom: 1px solid #ddd;
}
li label {
float: left;
cursor: pointer;
}
li label li input {
vertical-align: middle;
margin-right: 6px;
position: relative;
top: -1px;
}
li button {
float: right;
display: none;
margin-top: 3px;
}
li:before {
content: initial;
}
li:last-child {
border-bottom: none;
}
li:hover {
background-color: #ddd;
}
li:hover button {
display: block;
}
</style>