通过vue封装弹窗组件
大部分vue对效果的封装,有3个方式:
- 普通公共组件封装:
涉及东西,父子组件之间的传值和通过 v-modal 指令监听父子间的数据
- 通过渲染函数封装组件:
render函数运用
- 通过混合封装组件:
mixins,extends使用
共性:
vue的插槽使用:
1. 普通插槽:父组件向子组件 传dom结构的
2. 具名插槽: 父组件向子组件 根据插槽不同名称,传dom结构的
3. 作用域插槽: 在书写插槽内容时可以获取到插槽作用域的值
概括就是v-slot :后边是插槽名称,=后边是组件内部绑定作用域值的映射。
4. 结构插槽: 就是 使用 es6 解构赋值语法 获取域中的属性
1. popup通用组件封装
<template>
<div class="popup" >
<transition name="maskfade">
<div class="mask" @click="$emit('on-visible-change', !show)" v-if="show"></div>
</transition>
<transition :name="position + 'Slide'">
<div class="view" :class="position" v-if="show">
<!-- 比如这是头部插槽,可以控制 关闭操作的 样式和逻辑 -->
<slot name="header"/>
<!-- 比如这是内容插槽,可以放入自己的 交互组件 比如 下拉框,联动的。。等等-->
<slot name="content"/>
<!--具名插槽 -->
<slot name= "bottom" :list="list" />
</div>
</transition>
</div>
</template>
<script>
export default {
props: {
show: Boolean,
position: String
},
model: {
prop: 'show',
event: 'on-visible-change',
},
data() {
return {
list: [1,2,3,4]//为了模拟 作用域插槽提供数据
}
},
computed: {
classObject: function() {
// return this.
}
}
}
</script>
<style>
.mask {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
z-index: 1;
background-color: #000;
}
.view {
background-color: #fff;
position: absolute;
z-index: 1000;
}
.bottom {
width: 100%;
height: 12.5rem;
left: 0;
bottom: 0;
}
.top {
width: 100%;
height: 12.5rem;
left: 0;
top: 0;
}
.left {
width: 50%;
height: 100vh;
left: 0;
bottom: 0;
}
.right {
width: 50%;
height: 100vh;
right: 0;
bottom: 0;
}
/* vue中的过渡动画定义 */
/* 遮罩层过渡 */
.maskfade-enter,.maskfade-leave-to {
opacity: 0;
}
.maskfade-enter-active,.maskfade-leave-active {
transition: all .3s linear;
}
.maskfade-enter-to, .maskfade-leave {
opacity: 1;
}
/* 内容层过渡 */
/* bottom */
.bottomSlide-enter,.bottomSlide-leave-to {
transform: translateY(100%);
}
.bottomSlide-enter-active, .bottomSlide-leave-active {
transition: all .3s linear;
}
.bottomSlide-enter-to, .bottomSlide-leave{
transform: translateY(0%);
}
/* top */
.topSlide-enter,.topSlide-leave-to {
transform: translateY(-100%);
}
.topSlide-enter-active, .topSlide-leave-active {
transition: all .3s linear;
}
.topSlide-enter-to, .topSlide-leave{
transform: translateY(0%);
}
/* left */
.leftSlide-enter,.leftSlide-leave-to {
transform: translateX(-100%);
}
.leftSlide-enter-active, .leftSlide-leave-active {
transition: all .3s linear;
}
.leftSlide-enter-to, .leftSlide-leave{
transform: translateX(0%);
}
/* right */
.rightSlide-enter,.rightSlide-leave-to {
transform: translateX(100%);
}
.rightSlide-enter-active, .rightSlide-leave-active {
transition: all .3s linear;
}
.rightSlide-enter-to, .rightSlide-leave{
transform: translateX(0%);
}
</style>
父组件调用
<template>
<div class="mixins">
<button @click="showClick">test</button>
<Popup v-model="show" position="top">
<template v-slot:header>
<div>
我是头部的slot
</div>
</template>
<template v-slot:content>
<div>
我是内容的slot
</div>
</template>
<template v-slot:bottom="myList">
<div v-for="(item, index) in myList.list" :key="index">
我是 具名插槽 {{index}}
</div>
</template>
</Popup>
</div>
</template>
<script>
import Popup from "@/components/popup/Popup.vue"
export default {
components: {
Popup
},
data() {
return {
show: false
}
},
methods: {
showClick() {
this.show = !this.show;
}
},
}
</script>
效果:
1616033366(1).png
总结:
-
不论写什么组件,首先你必须可以通过原生js 亲自的去操作dom, 就想之前文章弹窗封装(一)/咋样动态节点实现过渡动画;这篇文章主要介绍实现原理。
-
然后通过 常见的 js和jquery 封装手段,去封装弹窗组件;弹窗封装(二)/深入体验闭包,this指向
只要有这样通过这2步才能深刻 体验 js的 强大的魅力;深入理解:上下文(this指向),作用域, 通过方法之间调用会转让控制权的目的是什么,闭包使用优点, 模块化区分,面向对象和面向过程
;
- vue封装时候,让我们比原生封装简化很多里面的细节,
就是最核心的数据驱动视图 代替 操作dom,还有属性和方法之间的调用也简化很多,因为所有的方法都挂在当前实例对象上,通过es6语法不要考虑 上下文问题,简化我们的封装思想
2. 通过过 混入 封装弹窗对象(里面有坑,解决这种模式封装可以控制 dom节点的 插入动画实现)
解决原理: 动态的dom节点添加过渡动画呢一定要注意js单线程执行同步任务,但是我们的过渡动画是有时间段的,也就是两种状态的。在js单线程执行,尤其在同步任务中,所有的执行逻辑都是同步进行,也就是说 创建遮罩层和添加show类名是同时的,所以导致m没有效果我们要把添加过渡最后类名,添加到异步队列中执行。setTimeout()实现宏观任务队列
敬请期待
3. 通过过 渲染 封装弹窗对象(里面有坑,咋样灵活高效控制一个节点的样式变化)
敬请期待
万水千山总是情,点波关注行不行(●'◡'●)!!!
网友评论