本文版权归 “公众号 | 前端一万小时” 所有,欢迎转载!
转载请注明出处,未经同意,不可修改文章内容。
🔥🔥🔥本系列文章已在“公众号 | 前端一万小时”更新完毕,有需要的小伙伴可按需前往查看。
🔥🔥🔥“前端一万小时”两大明星专栏——“从零基础到轻松就业”、“前端面试刷题”,已于本月大改版,合二为一,干货满满,欢迎点击公众号菜单栏各模块了解。
打开编辑器,准备好一份代码,点击“切换”显示/隐藏时有渐隐渐现的动画效果:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>前端一万小时-Vue 中的动画封装</title>
<script src="./vue.js"></script>
<style>
.v-enter,
.v-leave-to {
opacity: 0;
}
.v-enter-active,
.v-leave-active {
transition: opacity 1s;
}
</style>
</head>
<body>
<div id="root">
<transition>
<div v-if="show">Hello,前端一万小时</div>
</transition>
<button @click="handleBtnClick">切换</button>
</div>
<script>
var vm = new Vue({
el: "#root",
data: {
show: true
},
methods: {
handleBtnClick: function() {
this.show = !this.show
}
}
})
</script>
</body>
</html>
1 封装渐隐渐现动画效果
❓如何渐隐渐现的动画效果能够复用?
答:可以对渐隐渐现的动画效果进行封装。
<body>
<div id="root">
<fade :show="show"> <!-- 4️⃣使用 fade 组件:传一个 show 变量,它等于父组件的 show。 -->
<!-- 2️⃣
2️⃣-①:去除 div 外的 transition 标签; -->
<div>Hello,前端一万小时</div>
</fade>
<button @click="handleBtnClick">切换</button>
</div>
<script>
Vue.component("fade", { // 1️⃣新建名为 fade 的组件;
props: ["show"], /*
3️⃣
3️⃣-①:接收父组件传来的 show;
*/
template: `
<transition>
<slot v-if="show"></slot>
</transition>
` // 2️⃣-②:在模板中添加 transition 标签并增加 slot 插槽;
// 3️⃣-②:在 slot 中通过 show 来判断内容是否显示;
})
var vm = new Vue({
el: "#root",
data: {
show: true
},
methods: {
handleBtnClick: function() {
this.show = !this.show
}
}
})
</script>
</body>
完成后,刷新页面查看效果:
2 使用封装好的渐隐渐现效果
❓封装之后,如何在另一个元素上使用?
答:使用方法很简单,可以分别传入两个 DOM 元素,然后两个元素都会有渐隐渐现效果。
<div id="root">
<fade :show="show"> <!-- 1️⃣div 元素; -->
<div>Hello,前端一万小时</div>
</fade>
<fade :show="show"> <!-- 2️⃣h1 元素。 -->
<h1>Hello,前端一万小时</h1>
</fade>
<button @click="handleBtnClick">切换</button>
</div>
3 把样式一起封装进动画组件
❓如何可以调用动画组件并且不用再单独写 CSS 样式?
答:可以把样式一起封装到动画组件里,使用 JS 动画而不使用 CSS 动画。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>前端一万小时-Vue 中的动画封装</title>
<script src="./vue.js"></script>
<!-- 1️⃣使用 JS 动画,移除此处多余的 CSS 样式; -->
</head>
<body>
<div id="root">
<fade :show="show">
<div>Hello,前端一万小时</div>
</fade>
<fade :show="show">
<h1>Hello,前端一万小时</h1>
</fade>
<button @click="handleBtnClick">切换</button>
</div>
<script>
Vue.component("fade", {
props: ["show"],
// 2️⃣给 transition 添加 before-enter 钩子执行 handleBeforeEnter 函数;
// 4️⃣添加 enter 钩子,在 before-enter 钩子执行完成后执行 handleEnter 函数;
template: `
<transition @before-enter="handleBeforeEnter" @enter="handleEnter">
<slot v-if="show"></slot>
</transition>
`,
// 3️⃣在 fade 的 methods 中定义 handleBeforeEnter 函数:
methods: {
handleBeforeEnter: function(el) { // 3️⃣-①:handleBeforeEnter 接收一个 el 参数;
el.style.color = "red" // 3️⃣-②:让元素的样式变为红色;
},
handleEnter: function(el, done) { // 4️⃣-①:handleEnter 接收 el 和 done 两个参数;
setTimeout(() => {
el.style.color = "green" // 4️⃣-②:让元素两秒后变为绿色;
done() // 4️⃣-③:在动画结束时手动调用 done 回调函数;
}, 2000)
}
}
})
var vm = new Vue({
el: "#root",
data: {
show: true
},
methods: {
handleBtnClick: function() {
this.show = !this.show
}
}
})
</script>
</body>
</html>
把动画样式封装进组件的效果,元素显示时先变红,2 秒后变成绿色:
这种类型的动画封装是比较推荐的,因为它可以完整把所有动画的实现封装在一个组件里面。而使用时,外部只需要调用组件,并且不需要再在全局中写 style 样式。
祝好,qdywxs ♥ you!