$nextTick
这是一个生命周期钩子
this.$nextTick(回调函数)在下一次DOM更新结束后执行其指定的回调
什么时候用:当改变数据后,要基于更新后的新DOM进行某些操作时,要在nextTick所指定的回调函数中执行
使用 $nextTick 优化 Todo-List
src/components/MyItem.vue
<template>
<li>
<label>
<input type="checkbox" :checked="todo.done" @change="handleCheck(todo.id)"/>
<span v-show="!todo.isEdit">{{ todo.title }}</span>
<input type="text" v-show="todo.isEdit" :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>
</template>
<script>
export default {
name: "MyItem",
props: ["todo"], // 声明接收todo
methods: {
handleCheck(id) { // 勾选or取消勾选
// 通知App组件将对应的todo对象的done值取反
// this.checkTodo(id)
this.$bus.$emit("checkTodo", id);
},
handleDelete(id) { // 删除
if (confirm("确定删除吗?")) {
// 通知App组件将对应的todo对象删除
// this.deleteTodo(id)
this.$bus.$emit('deleteTodo',id)
}
},
handleEdit(todo) { // 编辑
if (todo.hasOwnProperty("isEdit")) {
todo.isEdit = true;
} else {
this.$set(todo, "isEdit", true);
}
this.$nextTick(function () {
this.$refs.inputTitle.focus();
});
},
handleBlur(todo, e) { // 失去焦点回调(真正执行修改逻辑)
todo.isEdit = false;
if (!e.target.value.trim()) return alert("输入不能为空!");
this.$bus.$emit("updateTodo", todo.id, e.target.value);
},
},
};
</script>
<template>
<li>
<label>
<input type="checkbox" :checked="todo.done" @change="handleCheck(todo.id)"/>
<span v-show="!todo.isEdit">{{ todo.title }}</span>
<input type="text" v-show="todo.isEdit" :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>
</template>
<script>
export default {
name: "MyItem",
props: ["todo"], // 声明接收todo
methods: {
handleCheck(id) { // 勾选or取消勾选
// 通知App组件将对应的todo对象的done值取反
// this.checkTodo(id)
this.$bus.$emit("checkTodo", id);
},
handleDelete(id) { // 删除
if (confirm("确定删除吗?")) {
// 通知App组件将对应的todo对象删除
// this.deleteTodo(id)
this.$bus.$emit('deleteTodo',id)
}
},
handleEdit(todo) { // 编辑
if (todo.hasOwnProperty("isEdit")) {
todo.isEdit = true;
} else {
this.$set(todo, "isEdit", true);
}
this.$nextTick(function () {
this.$refs.inputTitle.focus();
});
},
handleBlur(todo, e) { // 失去焦点回调(真正执行修改逻辑)
todo.isEdit = false;
if (!e.target.value.trim()) return alert("输入不能为空!");
this.$bus.$emit("updateTodo", todo.id, e.target.value);
},
},
};
</script>
过渡与动画
Vue封装的过度与动画:在插入、更新或移除DOM元素时,在合适的时候给元素添加样式类名
写法
1
准备好样式
○
元素进入的样式
ⅰ
v-enter 进入的起点
ⅱ
v-enter-active 进入过程中
ⅲ
v-enter-to 进入的终点
○
元素离开的样式
ⅰ
v-leave 离开的起点
ⅱ
v-leave-active 离开过程中
ⅲ
v-leave-to 离开的终点
2
使用<transition>包裹要过度的元素,并配置name属性,此时需要将上面样式名的v换为name
3
要让页面一开
<transition name="hello" appear>
<h1 v-show="isShow">你好啊!</h1>
</transition>
<style>
.hello-enter-active{
animation: hello 0.5s linear;
}
.hello-leave-active{
animation: hello 0.5s linear reverse;
}
@keyframes hello {
from{
transform: translateX(-100%);
}
to{
transform: translateX(0px);
}
}
</style>
始就显示动画,需要添加appear