视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
使用Vue组件实现一个简单弹窗效果
2020-11-27 22:15:50 责编:小采
文档

最近在使用element-ui框架,用到了Dialog对话框组件,大致实现的效果,跟我之前自己在移动端项目里面弄的一个弹窗组件差不太多。然后就想着把这种弹窗组件的实现方式与大家分享一下,下面本文会带着大家手摸手实现一个弹窗组件。

本文主要内容会涉及到弹窗遮罩的实现, slot 插槽的使用方式, props 、 $emit 传参,具体组件代码也传上去了。如果喜欢的话可以点波赞/关注,支持一下,希望大家看完本文可以有所收获。

组件最后实现的效果

 

实现步骤

  1. 先搭建组件的html和css样式,遮罩层和内容层。
  2. 定制弹窗内容:弹窗组件通过 slot 插槽接受从父组件那里传过来弹窗内容。
  3. 定制弹窗样式:弹窗组件通过 props 接收从父组件传过来的弹窗宽度,上下左右的位置。
  4. 组件开关:通过父组件传进来的 props 控制组件的显示与隐藏,子组件关闭时通过事件 $emit 触发父组件改变值。

1.搭建组件的html和css样式。

html结构:一层遮罩层,一层内容层,内容层里面又有一个头部title和主体内容和一个关闭按钮。

下面是组件中的html结构,里面有一些后面才要加进去的东西,如果看不懂的话可以先跳过,

<template>
 <div class="dialog">
 <!--外层的遮罩 点击事件用来关闭弹窗,isShow控制弹窗显示 隐藏的props-->
 <div class="dialog-cover back" v-if="isShow" @click="closeMyself"></div>
 <!-- transition 这里可以加一些简单的动画效果 -->
 <transition name="drop">
 <!--style 通过props 控制内容的样式 -->
 <div class="dialog-content" :style="{top:topDistance+'%',width:widNum+'%',left:leftSite+'%'}" v-if="isShow">
 <div class="dialog_head back">
 <!--弹窗头部 title-->
 <slot name="header">提示信息</slot>
 </div>
 <div class="dialog_main" :style="{paddingTop:pdt+'px',paddingBottom:pdb+'px'}">
 <!--弹窗的内容-->
 <slot name="main">弹窗内容</slot>
 </div>
 <!--弹窗关闭按钮-->
 <div class="foot_close" @click="closeMyself">
 <div class="close_img back"></div>
 </div>
 </div>
 </transition>
 </div>
</template>

下面是组件中的主要的css样式,里面都做了充分的注释,主要通过 z-index 和 background 达到遮罩的效果,具体内容的css可以根据自己的需求来设置。

<style lang="scss" scoped>
 // 最外层 设置position定位 
 .dialog {
 position: relative;
 color: #2e2c2d;
 font-size: 16px;
 }
 // 遮罩 设置背景层,z-index值要足够大确保能覆盖,高度 宽度设置满 做到全屏遮罩
 .dialog-cover {
 background: rgba(0,0,0, 0.8);
 position: fixed;
 z-index: 200;
 top: 0;
 left: 0;
 width: 100%;
 height: 100%;
 }
 // 内容层 z-index要比遮罩大,否则会被遮盖,
 .dialog-content{
 position: fixed;
 top: 35%;
 // 移动端使用felx布局 
 display: flex;
 flex-direction: column;
 justify-content: center;
 align-items: center;
 z-index: 300;
 }
</style>

2. 通过 slot 定制弹窗内容

这一步,只要理解了 slot 的作用以及用法,就没有问题了。

单个插槽:

<slot>这是在没有slot传进来的时候,才显示的弹窗内容</slot>
上面是单个插槽也叫默认插槽,在父组件中使用插槽的正确姿势:

<my-component>
 <!--在my-component里面的所有内容片段都将插入到slot所在的DOM位置,并且会替换掉slot标签-->
 <!--这两个p标签,将替换整个slot标签里面的内容-->
 <p>这是一些初始内容</p>
 <p>这是更多的初始内容</p>
</my-component>

ps:如果子组件里面包含 slot 插槽,那么上面的p标签的内容将会被丢弃。

具名插槽:

所谓的具名插槽,即为 slot 标签赋一个 name 属性,具名插槽可以父组件中不同的内容片段放到子组件的不同地方,具名插槽还是可以拥有一个默认插槽。下面可以看一下弹窗组件插槽的使用方式:

<div class="dialog_head back ">
 <!--弹窗头部 title-->
 <slot name="header">提示信息</slot>
 </div>
 <div class="dialog_main " :style="{paddingTop:pdt+'px',paddingBottom:pdb+'px'}">
 <!--弹窗的内容-->
 <slot name="main">弹窗内容</slot>
 </div>

在父组件中的使用方式:

将弹窗组件引入要使用的组件中,并通过 components 注册成为组件。
父组件中弹窗组件插槽的使用方法如下。

<dialogComponent>

 <div slot="header">插入到name为header的slot标签里面</div>
 <div class="dialog_publish_main" slot="main">
 这里是内容插入到子组件的slot的name为main里面,可以在父组件中添加class定义样式,事件类型等各种操作
 </div>
</dialogComponent>

关于组件中用到的插槽的介绍就到这里了,插槽在弹窗组件中的应用是一个典型的栗子,可以看到插槽作用相当强大,而插槽本身的使用并不难,同学们爱上插槽了没有?

3.通过 props 控制弹窗显隐&&定制弹窗style

psops 是Vue中父组件向子组件传递数据的一种方式,不熟悉的小伙伴们可以看一下 props文档 。

因为弹窗组件都是引到别的组件里面去用的,为了适合不同组件场景中的弹窗,所以弹窗组件必须具备一定的可定制性,否则这样的组件将毫无意义,下面介绍一下props的使用方式,以弹窗组件为例:

首先需要在被传入的组件中定义props的一些特性,验证之类的。
然后在父组件中绑定props数据。

<script>
export default {
 props: {
 isShow: { 
 //弹窗组件是否显示 默认不显示
 type: Boolean,
 default: false,
 required:true, //必须
 },
 //下面这些属性会绑定到div上面 详情参照上面的html结构
 // 如: :style="{top:topDistance+'%',width:widNum+'%'}"
 widNum:{ 
 //内容宽度
 type: Number,
 default:86.5
 },
 leftSite:{
 // 左定位
 type: Number,
 default:6.5
 },
 topDistance: {
 //top上边距
 type: Number,
 default:35
 },
 pdt:{
 //上padding
 type: Number,
 default:22
 },
 pdb:{
 //下padding
 type: Number,
 default:47
 }
 },
}
</script>

父组件中使用方式:

<dialogComponent :is-show="status.isShowPublish" :top-distance="status.topNum">
</dialogComponent>

ps:props传递数据不是双向绑定的,而是 单向数据流 ,父组件的数据变化时,也会传递到子组件中,这就意外着我们不应该在子组件中修改props。所以我们在关闭弹窗的时候就 需要通过 $emit 来修改父组件的数据 ,然后数据会自动传到子组件中。

现在基本上弹窗组件都已实现的差不多了,还差一个弹窗的关闭事件,这里就涉及到子组件往父组件传参了。

4. $emit 触发父组件事件修改数据,关闭弹窗

Vue中在子组件往父组件传参,很多都是通过 $emit 来触发父组件的事件来修改数据。

在子组件中,在点击关闭,或者遮罩层的时候触发下面这个方法:

methods: {
 closeMyself() {
 this.$emit("on-close"); 
 //如果需要传参的话,可以在"on-close"后面再加参数,然后在父组件的函数里接收就可以了。
 }
 }

父组件中的写法:

<dialogComponent :is-show="status.isShowPublish" :top-distance="status.topNum" @on-close="closeDialog"> 
 </dialogComponent>
 //"on-close是监听子组件的时间有没有触发,触发的时候执行closeDialog函数
methods:{
 closeDialog(){
 // this.status.isShowPublish=false;
 //把绑定的弹窗数组 设为false即可关闭弹窗
 },
}

可以用弹窗组件实现下列这种信息展示,或者事件交互:

 

弹窗组件代码

上面是把弹窗的每个步骤拆分开来,一步步解析的,每一步都说的比较清楚了,具体连起来的话,可以看看 代码 ,再结合文章就能理的很清楚了。

总结

以上所述是小编给大家介绍的使用Vue组件实现一个简单弹窗效果,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

下载本文
显示全文
专题