使用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 相关文章推荐
通过js获取div的background-image属性
Oct 15 Javascript
javascript继承机制实例详解
Nov 20 Javascript
基于jQuery实现仿51job城市选择功能实例代码
Mar 02 Javascript
jQuery实现打开页面渐现效果示例
Jul 27 Javascript
Bootstrap CDN和本地化环境搭建
Oct 26 Javascript
JS+HTML5 FileReader对象用法示例
Apr 07 Javascript
深入理解AngularJs-scope的脏检查(一)
Jun 19 Javascript
Vue的Flux框架之Vuex状态管理器
Jul 30 Javascript
解决Vue2.x父组件与子组件之间的双向绑定问题
Mar 06 Javascript
Jquery和CSS实现选择框重置按钮功能
Nov 08 jQuery
Node.js API详解之 readline模块用法详解
May 22 Javascript
详解JavaScript 的执行机制
Sep 18 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
PHP 编写的 25个游戏脚本
2009/05/11 PHP
用php实现选择排序的解决方法
2013/05/04 PHP
php获取目标函数执行时间示例
2014/03/04 PHP
PHP数据库操作二:memcache用法分析
2017/08/16 PHP
Ajax中的JSON格式与php传输过程全面解析
2017/11/14 PHP
你的编程语言可以这样做吗?
2006/09/07 Javascript
javascript最常用与实用的创建类的代码
2010/08/12 Javascript
推荐9款炫酷的基于jquery的页面特效
2014/12/07 Javascript
JS判断字符串包含的方法
2015/05/05 Javascript
Node.js 回调函数实例详解
2017/07/06 Javascript
Angular2 父子组件通信方式的示例
2018/01/29 Javascript
使用vue-cli编写vue插件的方法
2018/02/26 Javascript
JavaScript两种计时器的实例讲解
2019/01/31 Javascript
原生JS forEach()和map()遍历的区别、兼容写法及jQuery $.each、$.map遍历操作
2019/02/27 jQuery
JavaScript中while循环的基础使用教程
2020/08/11 Javascript
连接Python程序与MySQL的教程
2015/04/29 Python
python使用mysql数据库示例代码
2017/05/21 Python
Python SqlAlchemy动态添加数据表字段实例解析
2018/02/07 Python
python中abs&amp;map&amp;reduce简介
2018/02/20 Python
python得到单词模式的示例
2018/10/15 Python
Python+Tensorflow+CNN实现车牌识别的示例代码
2019/10/11 Python
TENSORFLOW变量作用域(VARIABLE SCOPE)
2020/01/10 Python
python开发入门——列表生成式
2020/09/03 Python
总结Pyinstaller的坑及终极解决方法(小结)
2020/09/21 Python
Python之京东商品秒杀的实现示例
2021/01/06 Python
python批量生成身份证号到Excel的两种方法实例
2021/01/14 Python
日语专业毕业生求职信
2013/12/04 职场文书
高中毕业的自我鉴定
2013/12/09 职场文书
学习十八大精神心得体会
2013/12/31 职场文书
军训教官感言
2014/03/02 职场文书
作风整顿个人剖析材料
2014/10/06 职场文书
2014购房个人委托书范本
2014/10/12 职场文书
总经理聘用协议书
2015/09/21 职场文书
MySQL 外键约束和表关系相关总结
2021/06/20 MySQL
使用 Apache Superset 可视化 ClickHouse 数据的两种方法
2021/07/07 Servers
spring cloud gateway中如何读取请求参数
2021/07/15 Java/Android