使用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 相关文章推荐
重定向实现代码
Nov 20 Javascript
来自国外的页面JavaScript文件优化
Dec 08 Javascript
一个挺有意思的Javascript小问题说明
Sep 26 Javascript
JavaScript实现twitter puddles算法实例
Dec 06 Javascript
JavaScript Length 属性的总结
Nov 02 Javascript
js创建对象的方法汇总
Jan 07 Javascript
bootstrap布局中input输入框右侧图标点击功能
May 16 Javascript
VUE元素的隐藏和显示(v-show指令)
Jun 23 Javascript
vue与TypeScript集成配置最简教程(推荐)
Oct 17 Javascript
vue.js2.0 实现better-scroll的滚动效果实例详解
Aug 13 Javascript
详解关于微信setData回调函数中的坑
Feb 18 Javascript
ES5新增数组的实现方法
May 12 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 管理系统程序中的后门
2009/08/05 PHP
Laravel框架基于ajax实现二级联动功能示例
2019/01/17 PHP
PHP实现八皇后算法
2019/05/06 PHP
jscript之List Excel Color Values
2007/06/13 Javascript
jQuery下实现等待指定元素加载完毕(可改成纯js版)
2013/07/11 Javascript
JS不间断向上滚动效果代码
2013/12/25 Javascript
在JavaScript中处理字符串之fontcolor()方法的使用
2015/06/08 Javascript
js实现简单的网页换肤效果
2017/01/18 Javascript
简单的jQuery拖拽排序效果的实现(增强动态)
2017/02/09 Javascript
js实现PC端和移动端刮卡效果
2020/03/27 Javascript
关于不同页面之间实现参数传递的几种方式讨论
2017/02/13 Javascript
jQuery自定义元素右键点击事件(实现案例)
2017/04/28 jQuery
详解Nodejs之静态资源处理
2017/06/05 NodeJs
浅谈Express异步进化史
2017/09/09 Javascript
Vue CLI3.0中使用jQuery和Bootstrap的方法
2019/02/28 jQuery
JavaScript多种页面刷新方法小结
2019/04/04 Javascript
vue+axios全局添加请求头和参数操作
2020/07/24 Javascript
[02:41]DOTA2亚洲邀请赛小组赛第三日 赛事回顾
2015/02/01 DOTA
详解Python中的__new__()方法的使用
2015/04/09 Python
Python实现批量读取word中表格信息的方法
2015/07/30 Python
Python中的time模块与datetime模块用法总结
2016/06/30 Python
Python实现生成随机日期字符串的方法示例
2017/12/25 Python
详解Python 正则表达式模块
2018/11/05 Python
python 读取鼠标点击坐标的实例
2018/12/29 Python
利用Python实现kNN算法的代码
2019/08/16 Python
python 调试冷知识(小结)
2019/11/11 Python
Tensorflow训练MNIST手写数字识别模型
2020/02/13 Python
Python Django中间件使用原理及流程分析
2020/06/13 Python
校班主任推荐信范文
2013/12/03 职场文书
八一建军节营销活动方案
2014/08/31 职场文书
反对形式主义、官僚主义、享乐主义和奢靡之风整改措施
2014/09/17 职场文书
出差报告格式模板
2014/11/06 职场文书
医院办公室主任岗位职责
2015/04/01 职场文书
免职通知
2015/04/23 职场文书
MySQL Router实现MySQL的读写分离的方法
2021/05/27 MySQL
python机器学习实现oneR算法(以鸢尾data为例)
2022/03/03 Python