使用Vue组件实现一个简单弹窗效果


Posted in Javascript onApril 23, 2018

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

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

组件最后实现的效果

使用Vue组件实现一个简单弹窗效果 

实现步骤

  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组件实现一个简单弹窗效果 

弹窗组件代码

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

总结

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

Javascript 相关文章推荐
用jQuery技术实现Tab页界面之二
Sep 21 Javascript
jquery 分页控件实现代码
Nov 30 Javascript
javascript权威指南 学习笔记之null和undefined
Sep 25 Javascript
Js操作树节点自动折叠展开的几种方法
May 05 Javascript
自动完成的搜索框javascript实现
Feb 26 Javascript
jQuery中通过ajax调用webservice传递数组参数的问题实例详解
May 20 Javascript
js将滚动条滚动到指定位置的简单实现方法
Jun 25 Javascript
protractor的安装与基本使用教程
Jul 07 Javascript
利用yarn代替npm管理前端项目模块依赖的方法详解
Sep 04 Javascript
不使用JavaScript实现菜单的打开和关闭效果demo
May 01 Javascript
layui点击导航栏刷新tab页的示例代码
Aug 14 Javascript
vue生成文件本地打开查看效果的实例
Sep 06 Javascript
深入理解JavaScript和TypeScript中的class
Apr 22 #Javascript
原生JS进行前后端同构
Apr 22 #Javascript
如何以Angular的姿势打开Font-Awesome详解
Apr 22 #Javascript
vue移动端实现下拉刷新
Apr 22 #Javascript
实例讲解Vue.js中router传参
Apr 22 #Javascript
用Vue写一个分页器的示例代码
Apr 22 #Javascript
vue-cli3.0 特性解读
Apr 22 #Javascript
You might like
Laravel框架中实现使用阿里云ACE缓存服务
2015/02/10 PHP
centos7上编译安装php7以php-fpm方式连接apache
2018/11/08 PHP
phpStorm2020 注册码
2020/09/17 PHP
javascript之大字符串的连接的StringBuffer 类
2007/05/08 Javascript
javascript对话框使用方法(警告框 javascript确认框 提示框)
2014/01/07 Javascript
实现placeholder效果的方案汇总
2015/06/11 Javascript
Javascript编写2048小游戏
2015/07/07 Javascript
JQuery实现左右滚动菜单特效
2015/09/28 Javascript
基于BootStrap Metronic开发框架经验小结【六】对话框及提示框的处理和优化
2016/05/12 Javascript
Boostrap实现的登录界面实例代码
2016/10/09 Javascript
JavaScript队列的应用实例详解【经典数据结构】
2017/04/12 Javascript
label+input实现按钮开关切换效果的实例
2017/08/16 Javascript
js匿名函数使用&amp;传参(实例)
2017/09/08 Javascript
vue axios请求超时的正确处理方法
2018/04/02 Javascript
webpack实现一个行内样式px转vw的loader示例
2018/09/13 Javascript
如何使用CSS3和JQuery easing 插件制作绚丽菜单
2019/06/18 jQuery
javascript History对象原理解析
2020/02/17 Javascript
JavaScript实现打砖块游戏
2020/02/25 Javascript
Python设计模式之观察者模式实例
2014/04/26 Python
python统计文本字符串里单词出现频率的方法
2015/05/26 Python
Python语言生成水仙花数代码示例
2017/12/18 Python
python实现微信自动回复机器人功能
2019/07/11 Python
python对验证码降噪的实现示例代码
2019/11/12 Python
python FTP批量下载/删除/上传实例
2019/12/22 Python
Python字符编码转码之GBK,UTF8互转
2020/02/09 Python
使用python求解二次规划的问题
2020/02/29 Python
北美Newegg打造的全球尖货海购平台:tt海购
2018/09/28 全球购物
家长评语和期望
2014/02/10 职场文书
房地产开盘策划方案
2014/02/10 职场文书
道德之星事迹材料
2014/05/03 职场文书
上课随便讲话检讨书
2014/09/12 职场文书
狼牙山五壮士观后感
2015/06/09 职场文书
国富论读书笔记
2015/06/26 职场文书
详解Django的MVT设计模式
2021/04/29 Python
python numpy中multiply与*及matul 的区别说明
2021/05/26 Python
Python可变集合和不可变集合的构造方法大全
2021/12/06 Python