使用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 相关文章推荐
3款实用的在线JS代码工具(国外)
Mar 15 Javascript
jQuery学习笔记 获取jQuery对象
Sep 19 Javascript
自动最大化窗口的Javascript代码
May 22 Javascript
Javascript中的异步编程规范Promises/A详细介绍
Jun 06 Javascript
JQuery入门基础小实例(1)
Sep 17 Javascript
js实现简单计算器
Nov 22 Javascript
值得分享的轻量级Bootstrap Table表格插件
May 30 Javascript
基于JS代码实现图片在页面中旋转效果
Jun 16 Javascript
javascript定时器的简单应用示例【控制方块移动】
Jun 17 Javascript
vue cli安装使用less的教程详解
Jul 12 Javascript
el-input 标签中密码的显示和隐藏功能的实例代码
Jul 19 Javascript
vue实现移动端省市区选择
Sep 27 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实现paypal整合方法
2010/11/28 PHP
PHP CURL模拟登录新浪微博抓取页面内容 基于EaglePHP框架开发
2012/01/16 PHP
PHP实现简单汉字验证码
2015/07/28 PHP
Yii框架上传图片用法总结
2016/03/28 PHP
thinkPHP5.0框架模块设计详解
2017/03/18 PHP
编写Js代码要注意的几条规则
2010/09/10 Javascript
详解Javascript 装载和执行
2014/11/17 Javascript
js动态创建及移除div的方法
2015/06/03 Javascript
Jquery 分页插件之Jquery Pagination
2015/08/25 Javascript
jquery实现经典的淡入淡出选项卡效果代码
2015/09/22 Javascript
js 将input框中的输入自动转化成半角大写(税号输入框)
2017/02/16 Javascript
微信小程序实现图片懒加载的示例代码
2017/12/13 Javascript
Node Puppeteer图像识别实现百度指数爬虫的示例
2018/02/22 Javascript
vue.js或js实现中文A-Z排序的方法
2018/03/08 Javascript
vue.js数据绑定操作详解
2018/04/23 Javascript
Python利用多进程将大量数据放入有限内存的教程
2015/04/01 Python
python计算一个序列的平均值的方法
2015/07/11 Python
老生常谈进程线程协程那些事儿
2017/07/24 Python
Python字典,函数,全局变量代码解析
2017/12/18 Python
Python设计模式之备忘录模式原理与用法详解
2019/01/15 Python
关于Pycharm无法debug问题的总结
2019/01/19 Python
解决pycharm运行程序出现卡住scanning files to index索引的问题
2019/06/27 Python
Python操作Word批量生成合同的实现示例
2020/08/28 Python
python实现简单的井字棋游戏(gui界面)
2021/01/22 Python
js实现移动端H5页面手指滑动刻度尺功能
2017/11/16 HTML / CSS
Maison Lab荷兰:名牌Outlet购物
2018/08/10 全球购物
大学应届毕业生个人求职信
2013/09/23 职场文书
应届毕业生个人求职自荐信
2014/01/06 职场文书
《生命 生命》教学反思
2014/04/19 职场文书
省级优秀班集体申报材料
2014/05/25 职场文书
民族精神月活动总结
2014/08/28 职场文书
管辖权异议上诉状
2015/05/23 职场文书
意外事故赔偿协议书
2016/03/22 职场文书
bootstrapv4轮播图去除两侧阴影及线框的方法
2022/02/15 HTML / CSS
Redis 中使用 list,streams,pub/sub 几种方式实现消息队列的问题
2022/03/16 Redis
《吸血鬼:避世 血猎》官宣4.27发售 系列首款大逃杀
2022/04/03 其他游戏