1.动画效果
<template>
<div>
<button @click="show = !show">显示/隐藏</button>
<!-- appear 一开始播放进场动画 :appear="true" 简写 appear -->
<transition name="hello" appear>
<h1 v-show="show">你好啊</h1>
</transition>
</div>
</template>
<script>
export default {
name: "TestV1",
data() {
return {
show: true,
};
},
};
</script>
<style scoped>
h1 {
background-color: orange;
}
/* 给transition起了名字 那么 下面的类选择器 的名字也要随之替换 */
.hello-enter-active {
/* 1秒钟播放完毕 匀速 */
animation: atguigu 1s linear;
}
.hello-leave-active {
/* 反转 */
animation: atguigu 1s linear reverse;
}
.v-enter-active {
/* 1秒钟播放完毕 匀速 */
animation: atguigu 1s linear;
}
.v-leave-active {
/* 反转 */
animation: atguigu 1s linear reverse;
}
/* .come {
/* 1秒钟播放完毕 匀速 */
/* animation: atguigu 1s linear; */
/* } */
/* .go { */
/* 反转 */
/* animation: atguigu 1s linear reverse; */
/* } */
/* 动画定义 关键帧 */
/* 给动画起个名字 atguigu */
@keyframes atguigu {
from {
transform: translateX(-100%);
}
to {
transform: translateX(0px);
}
}
</style>
2.使用过度去实现
<template>
<div>
<button @click="show = !show">显示/隐藏</button>
<!-- appear 一开始播放进场动画 :appear="true" 简写 appear -->
<transition name="hello" appear>
<h1 v-show="show">你好啊</h1>
</transition>
</div>
</template>
<script>
export default {
name: "TestV2",
data() {
return {
show: true,
};
},
};
</script>
<style scoped>
h1 {
background-color: orange;
/* transition: 1s linear; */
}
/* 进入的起点 离开的终点 */
.hello-enter,.hello-leave-to{
transform: translateX(-100%);
}
.hello-enter-active,.hello-leave-active{
transition: 1s linear;
}
/* 进入的终点 离开的起点*/
.hello-enter-to,.hello-leave{
transform: translateX(0);
}
</style>
3.多个元素的过度
<template>
<div>
<button @click="show = !show">显示/隐藏</button>
<!-- appear 一开始播放进场动画 :appear="true" 简写 appear -->
<transition-group name="hello" appear>
<h1 v-show="show" key="1">你好啊</h1>
<h1 v-show="!show" key="2">尚硅谷</h1>
</transition-group>
</div>
</template>
<script>
export default {
name: "TestV3",
data() {
return {
show: true,
};
},
};
</script>
<style scoped>
h1 {
background-color: orange;
/* transition: 1s linear; */
}
/* 进入的起点 离开的终点 */
.hello-enter,.hello-leave-to{
transform: translateX(-100%);
}
.hello-enter-active,.hello-leave-active{
transition: 1s linear;
}
/* 进入的终点 离开的起点*/
.hello-enter-to,.hello-leave{
transform: translateX(0);
}
</style>
4.集成第三方动画
主页
1.安装
npm install animate.css
别忘记这句话
import 'animate.css';
5.总结
把todoList案例加个动画
<template>
<transition
appear
name="animate__animated animate__bounce"
enter-active-class="animate__swing"
leave-active-class="animate__rotateOutUpRight"
>
<div
id="container"
@mouseover="handleMouseOver"
@mouseleave="handleMouseLeave"
>
<div id="d">
<input type="checkbox" v-model="todo.done" />
<span @click="info" v-show="!todo.showUpdate">{{ todo.title }}</span>
<!-- v-inputfocus="todo.showUpdate" -->
<input
type="text"
ref="updateInput"
v-model="updateTitle"
@keyup.enter="submitUpdate"
@blur="cancelUpdate"
v-show="todo.showUpdate"
/>
</div>
<div>
<button class="btn update" v-show="showDelete" @click="updateTodo">
修改
</button>
<button class="btn" v-show="showDelete" @click="deleteTodo">
删除
</button>
</div>
</div>
</transition>
</template>
<script>
import pubsub from "pubsub-js";
import "animate.css";
export default {
name: "TodoItem",
data() {
return {
todo: this.todoObj,
updateTitle: "",
showDelete: false,
};
},
methods: {
//todo.hasOwnProperty这个属性是否有api
removeFocus() {
// this.$refs.updateInput.blur();
},
info() {
console.log(this.todo);
},
handleMouseOver() {
this.showDelete = true;
},
handleMouseLeave() {
this.showDelete = false;
},
deleteTodo() {
// let a = this.$bus.$emit('removeTodo',this.todoObj.id)
// console.log(a===this.$bus);//a === vm
if (confirm("你确定要删除吗?")) {
pubsub.publish("removeTodo", this.todoObj.id);
}
},
updateTodo() {
if (this.todo.showUpdate) {
this.todo.showUpdate = false;
} else {
this.updateTitle = this.todo.title;
// this.$bus.$emit("updateTodoInputShow", this.todoObj.id, true);
this.todo.showUpdate = true;
//vue 提供api 在下次dom节点更新完毕后执行的回调
this.$nextTick(function () {
this.$refs.updateInput.focus();
// console.log(this.$refs.updateInput);
});
}
//vue 是等方法结束以后才回去解析模板, input框 focus 在display状态是不会聚焦的
},
submitUpdate() {
if (confirm("你确定要保存吗?")) {
if (this.updateTitle.trim() === "") {
alert("输入不能为空");
return;
}
this.$bus.$emit("updateTodo", this.todo.id, this.updateTitle);
}
this.todo.showUpdate = false;
},
cancelUpdate() {
this.todo.showUpdate = false;
},
},
props: {
todoObj: {
//传入的若是引用对象 则里面修改了,外面同样生效
type: Object,
required: true,
},
},
directives: {
// inputfocus(e,v){
// if (v) {
// e.focus();
// }
// }
// inputfocus: {
// inserted(element, value) {
// if (value) {
// element.focus();
// }
// },
// update(element, value) {
// if (value) {
// element.focus();
// }
// },
// },
},
};
</script>
<style scoped>
#container:hover {
background-color: #a09a9a;
}
#container {
display: flex;
justify-content: space-between; /* 水平居左 */
align-items: center; /* 垂直居中 */
width: 500px;
height: 30px;
border: 0.1px solid #ccc;
border-radius: 2px;
padding-left: 10px;
padding-top: 5px;
padding-bottom: 5px;
}
#container * {
padding: 5px;
}
.btn {
width: 50px;
height: 28px;
color: white;
background-color: #eb1212;
border: 1px solid #ccc;
border-radius: 5px;
padding: 5px;
margin-right: 15px;
cursor: pointer; /* 鼠标悬停时显示手型光标 */
transition: background-color 0.3s ease; /* 平滑过渡 */
}
.btn:hover {
background-color: #d10d0d; /* 鼠标悬停时颜色变化 */
}
.btn:active {
background-color: #a00; /* 按下时颜色变化 */
transform: translateY(2px); /* 按下时按钮下移效果 */
}
.update {
background-color: #1233eb;
margin-right: 5px;
}
.update:hover {
background-color: #4e70dc; /* 鼠标悬停时颜色变化 */
}
.update:active {
background-color: rgb(71, 0, 170); /* 按下时颜色变化 */
transform: translateY(2px); /* 按下时按钮下移效果 */
}
</style>