一、动画效果
keyframes 实现
1- Vue 中动画效果需要借助
transition
标签,该标签不会形成 HTML 结构2- 搭配
.v-enter-active
和.v-leave-active
可以实现元素进场和出场时的动画效果3-
我们在还可以给 transition 添加 name 属性,指定动画的名称,此时进场动画和出场动画的类名就需要修改成 .name-enter-active 和 .name-leave-active
如例子 2-1、2-2
4-
如果想要初始化的时候就有动画效果,可以使用给 transition 添加 appear 属性(或者添加 :appear=true)
<template>
<div>
<!-- 1-1 无 name appear 出现展示效果-->
<transition appear="true">
<h1 v-show="isShow">你好啊,Vue! !!</h1>
</transition>
<!--2-1 name为hello属性 -->
<transition name="hello" appear="true">
<h2 v-show="isShow">你好啊,Vue! !!</h2>
</transition>
<button @click="showFun">点击显示</button>
</div>
</template>
<script>
export default {
name: "Test",
data() {
return {
isShow: true,
};
},
methods: {
showFun() {
this.isShow = !this.isShow;
},
},
};
</script>
<style scoped>
h1 {
background-color: orange;
}
h2 {
background-color: yellow;
}
/* 1-2 */
.v-enter-active {
animation: demo1 0.5s linear;
}
.v-leave-active {
animation: demo1 0.5s linear reverse;
}
/* 2-2 name="hello" 写法 */
.hello-enter-active {
animation: demo1 2s linear;
}
.hello-leave-active {
animation: demo1 2s linear reverse;
}
@keyframes demo1 {
from {
transform: translateX(-100%);
}
to {
transform: translateX(0px);
}
}
</style>
二、 过渡效果
对于入场动画,如下 3个
v-enter
:进场的起点.v-enter-active
:进场特效激活全过程.v-enter-to
:进场的终点对于出场,如下3个
.v-leave
:出场的起点.v-leave-active
:出场特效激活全过程.v-leave-to
:出场的终点
<template>
<div>
<!-- 1-1 无 name appear 出现展示效果-->
<transition appear>
<h1 v-show="isShow">你好啊,Vue! !!</h1>
</transition>
<!--2-1 name为hello属性 -->
<transition name="hello" >
<h2 v-show="isShow">你好啊,Vue! !!</h2>
</transition>
<button @click="showFun">点击显示</button>
</div>
</template>
<script>
export default {
name: "Test",
data() {
return {
isShow: true,
};
},
methods: {
showFun() {
this.isShow = !this.isShow;
},
},
};
</script>
<style scoped>
h1 {
background-color: orange;
}
h2 {
background-color: yellow;
}
/* 1-2 */
.v-enter-active {
animation: demo1 0.5s linear;
}
.v-leave-active {
animation: demo1 0.5s linear reverse;
}
/* 2-2 hello */
.hello-enter-active {
animation: demo1 2s linear;
}
.hello-leave-active {
animation: demo1 2s linear reverse;
}
@keyframes demo1 {
from {
transform: translateX(-100%);
}
to {
transform: translateX(0px);
}
}
</style>
三、多个元素的过渡
transition-group:一般用于列表渲染
我们前面讲到的 transition 只能给一个元素添加动画,如果想要给多个元素添加动画,那么我们就需要使用到 ,并且需要给每个元素添加唯一的 key 值
<template>
<div>
<!--1- transition-group 多个元素的过渡 -->
<transition-group name="hello" appear>
<h1 v-show="!isShow" key="1">你好啊,Vue! !!</h1>
<h1 v-show="isShow" key="2">你好啊,Vue! !!</h1>
</transition-group>
<button @click="showFun">点击显示</button>
</div>
</template>
<script>
export default {
name: "Test",
data() {
return {
isShow: true,
};
},
methods: {
showFun() {
this.isShow = !this.isShow;
},
},
};
</script>
<style scoped>
h1 {
background-color: orange;
}
/* 1- 分开写 */
/* 进入的起点 */
.hello-enter {
transform: translateX(-100%);
}
/* 进入的终点 */
.hello-leave-to {
transform: translateX(0);
}
/* 离开的起点 */
.hello-leave {
transform: translateX(0);
}
/* 离开的终点 */
.hello-leave-to {
transform: translateX(-100%);
}
/* 2- 合并写法 */
/* 进入的起点 离开的终点*/
/* .hello-enter, .hello-leave-to{
transform: translateX(-100%);
} */
/* 来的整个过程 和走的过程 */
.hello-enter-active,
.hello-leave-active {
transition: 0.5s linear;
}
/* 离开的起点 离开的终点*/
/* .hello-leave, .hello-leave-to{
transform: translateX(0);
} */
</style>
四、动画插件
我们进入到 npm 官网搜索 animate.css,进入到它的主页:Animate.css | A cross-browser library of CSS animations.
使用步骤:
1- 安装css库
npm install animate.css --save
2- 引入import 'animate.css'
3-引入class
<h1 class="animate__animated animate__bounce">An animated element</h1>
4-
添加
enter-active-class
和leave-active-class
样式到元素节点中,属性值从刚才的侧边栏中选择
<template>
<div>
<!--1-第三方插件 动画 npm install animate.css --save 或者 yarn add animate.css -->
<transition-group
name="animate__animated animate__bounce"
enter-active-class="animate__swing"
leave-active-class="animate__fadeOut"
appear>
<h1 v-show="!isShow" key="3">你好啊,Vue! !!</h1>
<h1 v-show="isShow" key="4">你好啊,Vue! !!</h1>
</transition-group>
<button @click="showFun">点击显示</button>
</div>
</template>
<script>
// 引入css
import animated from 'animate.css'
export default {
name: "Test",
data() {
return {
isShow: true,
};
},
methods: {
showFun() {
this.isShow = !this.isShow;
},
},
};
</script>
<style scoped>
h1 {
background-color: orange;
}
</style>
三、修改TODOList 的过渡效果
此处有2种方法 在每个item上面包裹,或者用 transition-group 包裹真个 list
1- 在MyITem组件上面修改 transition
<template>
<!-- 1- transition 添加动画效果 -->
<transition name="todo" appear>
<li>
<label>
<input
type="checkbox"
:checked="todo.done"
@change="changeCheck(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="handleDelte(todo.id)">删除</button>
<!--编辑按钮 -->
<button
v-show="!todo.isEdit"
class="btn btn-edit"
@click="handleEdit(todo)"
>
编辑
</button>
</li>
</transition>
</template>
<script>
import pubsub from "pubsub-js";
export default {
name: "MyItem",
props: ["todo"],
mounted() {
console.log(this.todo);
},
methods: {
changeCheck(id) {
this.$bus.$emit("checkTodo", id);
},
handleDelte(id) {
if (confirm("确认删除吗?")) {
pubsub.publish("deleteTodo", id);
}
},
// 3- 编辑操作(点击编辑显示输入框,判断是否有isEdit属性,无则 $set 绑定属性)
handleEdit(todo) {
if (!todo.hasOwnProperty("isEdit")) {
//判断todo没有isEdit属性 追加属性
this.$set(todo, "isEdit", true);
} else {
todo.isEdit = !todo.isEdit;
}
//dom 节点演示渲染
// setTimeout(() => {
// this.$refs.inputTitle.focus();
// }, timeout);
this.$nextTick(function () {
this.$refs.inputTitle.focus();
});
},
//4- 失去焦点操作:保存数据
handleBlur(todo, e) {
todo.isEdit = !todo.isEdit;
if (!e.target.value.trim()) {
alert("输入不能为空!");
}
this.$bus.$emit("editTodo", todo.id, e.target.value);
},
},
};
</script>
<style scoped>
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: gray;
}
li:hover button {
display: block;
}
/* 2- 动画效果 */
/* 进入的起点 离开的终点*/
.todo-enter, .todo-leave-to{
transform: translateX(-100%);
}
/* 来的整个过程 和走的过程 */
.todo-enter-active,
.todo-leave-active {
transition: 0.5s linear;
}
/* 离开的起点 离开的终点*/
.todo-leave, .todo-leave-to{
transform: translateX(0);
}
</style>
2- 在MyList上面用 transition-group
<template>
<ul class="todo-main">
<!--1- transition-group 包裹list -->
<transition-group name="todo" appear>
<MyItem v-for="item in todos " :key="item.id" :todo="item" />
</transition-group>
</ul>
</template>
<script>
import MyItem from "./MyItem.vue";
export default {
name: "MyList",
components: {
MyItem,
},
// props:['todos','checkTodo','deleteTodo']
props: ["todos"],
};
</script>
<style scoped>
/*main*/
.todo-main {
margin-left: 0px;
border: 1px solid #ddd;
border-radius: 2px;
padding: 0px;
}
.todo-empty {
height: 40px;
line-height: 40px;
border: 1px solid #ddd;
border-radius: 2px;
padding-left: 5px;
margin-top: 10px;
}
/* 2-动画效果 */
/* 进入的起点 离开的终点*/
.todo-enter, .todo-leave-to{
transform: translateX(-100%);
}
/* 来的整个过程 和走的过程 */
.todo-enter-active,
.todo-leave-active {
transition: 0.5s linear;
}
/* 离开的起点 离开的终点*/
.todo-leave, .todo-leave-to{
transform: translateX(0);
}
</style>