详解用vue编写弹出框组件

前言

最近研究了用vue编写弹出框的组件,发现其实这里面的门道还是有很多的。这篇文完全是用来记录总结下最近的学习成果,同时也希望能够帮得上正在学习纠结的你~ps:本文假设你已经了解vue2.0相关框架,因此适合有一定vue2.0基础的同学阅读。

设计组件的思考

其实单纯的编写一个弹出框组件并不难,写一个模板,然后用v-if或者v-show指令还控制组件的出现与消失。真正困扰我的是,这个组件的调用方式,这个问题纠结了我好久。

调研了下资料,有些人建议,直接把组件标签插进模板中,然后通过直接控制组件的显示隐藏来控制组件。这样写有好处,就是结构清晰,一目了然,人家一看你的代码就知道你这个页面可能会有弹出框,并且编写的组件就更容易,只需关注内部方法就好了,也不存在事件调用的困扰,维护起来也特别容易。但是缺点也很明显,如果有多个弹窗,并且不知道会有几个弹窗的情况下,感觉就不太好做,并且这种提前写模板的形式,难免会在不弹窗的时候要下载一些js文件,有可能会造成性能浪费。

也有些人建议,在写好的弹出框组件之外再做一层封装,通过动态调用的方式来控制弹出框的显示与隐藏。这样写的好处是不用事先在模板里面写好该组件的标签,只需要在想调用的地方调用下该组件,就实现了按需使用的目的,符合之前传统前端框架的编码习惯。缺点就是感觉代码写起来比较复杂,层层嵌套,并且感觉这个与MVVM模式的状态驱动界面的思想相违背。

于是我天秤座的纠结病犯了,在选择哪种技术方案的问题上,思考了很久。但是网上搜了很多,发现还是后一种实现方法用的人比较多。后来我又研究了了elementUI和iView的弹出框组件,他们也是沿用的后一种方法,想了一下后一种方法虽然代码易读性不强,但是它真正模拟了浏览器默认的alert事件,在用户需要的地方来调用,一方面节省了代码量,另一方面也很容易解决多个弹窗的情况。最后还是决定用这种模式写一个简单的弹出框组件。主要是体会这其中的机理。废话不多说,来上干货了。有啥不对的地方还请大家多多指教。(ps:对于天秤座的我,虽然选择了后一种方法,但是内心还是钟爱第一种方法,并且后一种方法并没有足够的理由说服我呀,不知道哪位有识之士能够帮忙点醒一下我,晚辈感激不尽)。

alert组件设计

单独的设计alert弹出框的逻辑是很简单的,我就直接上代码了:

<template>
<transition name='fade'>
 <div class="alert" v-if="showAlert">
  <div class="wrap">
   <div class="head">{{title}}</div>
   <div class="body">
    <slot>
     <p>{{message}}</p>
    </slot>
   </div>
   <div class="foot">
    <div v-if="type === 'confirm'">
     <button class="btn-base" @click="sure">确定</button>
     <button class="btn-gray" @click="cancel">取消</button>
    </div>
    <div v-else-if="type === 'inform'">
     <button class="btn-base" @click="cancel">知道了</button>
    </div>
   </div>
  </div>
 </div>
</transition>
</template>
<script>
export default {
 name: 'alert',
 data() {
  return {
   showAlert: false,
  };
 },
 props: {
  title: {
   type: String,
   default: '提示',
  },
  message: {
   type: String,
  },
  type: { // 可以有confirm, 和inform两个类型
   type: String,
   default: 'confirm',
   validator(value) {
    return value === 'confirm' || value === 'inform';
   },
  },
  sureBtn: {
   type: Function,
  },
  cancelBtn: {
   type: Function,
  },
  context: {
   type: Object,
  },
 },
 methods: {
  cancel() {
   if (this.cancelBtn) {
    this.cancelBtn.apply(this.context);
   }
   this.close();
  },
  sure() {
   if (this.sureBtn) {
    this.sureBtn.apply(this.context);
   }
   this.close();
  },
  show() {
   this.showAlert = true;
  },
  close() {
   this.showAlert = false;
  },
 },
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang='scss'>
.alert {
 position: fixed;
 top: 0;
 left: 0;
 right: 0;
 bottom: 0;
 background: rgba(0,0,0, 0.8);
 z-index: 1000;
 transition: all .3s ease-in-out;
}
.wrap {
 position: absolute;
 z-index: 1002;
 min-width: 400px;
 background: #fff;
 left: 50%;
 top: 50%;
 transform: translate(-50%, -50%);
 border-radius: 4px;
}
.head {
 height: 40px;
 line-height: 40px;
 border-bottom: 1px solid #dedede;
 padding-left: 10px;
 color: #333;
}
.body {
 padding: 40px 20px;
 text-align: center;
}
.foot {
 height: 50px;
 text-align: center;
 button {
  margin-right: 20px;
  &:last-child {
   margin-right: 0;
  }
 }
}
</style>

这里只是写了简单的功能,并没有考虑更复杂的情况,比如按钮颜色定制,大小定制,z-index层级的考虑,遮罩层的统一管理等等,只是为了掌握编写弹出框的主要思想,所以没有写太多的情况。这里只细分了是确认框还是通知框,可以定制弹出框的内容、标题等一些简单的常规操作。

其实这个组件写好,就可以在页面用起来了,直接在对应页面插入这段,可以也可以用:

<!--template-->
<button @click="showAlert">点我</button>
<alert ref="alert">我是一个确认框</alert>
<!--javascript-->
...
methods: {
  showAlert() {
    this.$refs.alert.show();
  }
}
...

当然,如果真要这么用,这个组件还是需要修改一些东西的,比如事件抛出,当点击确定或者取消按钮的时候,需要emit对应的事件,以提供给父组件捕获,并做相应的处理。

动态插入到页面中

为了能让组件动态的插入到页面中,需要对上面的组件进行封装,利用Vue.extend机制,可以轻松的做到这种封装,直接上代码:

import Vue from 'vue';
import alert from './alert';
const AlertConstructor = Vue.extend(alert);
const div = document.createElement('div');
AlertConstructor.show = (options) => {
 document.body.appendChild(div);
 options.type = 'inform';
 const propsData = Object.assign({}, options);
 const alertInstance = new AlertConstructor({
  propsData,
 }).$mount(div);
 alertInstance.show();
};
AlertConstructor.confirm = (options) => {
 document.body.appendChild(div);
 options.type = 'confirm';
 const propsData = Object.assign({}, options);
 const alertInstance = new AlertConstructor({
  propsData,
 }).$mount(div);
 alertInstance.show();
};
export default AlertConstructor;

这里,show对应的是通知框,confirm对应的是确认框。我知道这种封装有点简单了,有很多情况没有考虑,比如有多个弹出框时的处理等。这里只是做了简单的封装,为的就是让大家明白此种封装主要思路是什么。

总结

这篇文章仅仅是对自己这几天摸索弹出框组件问题的一个简短的总结与思考。可能还不是很成熟,当做抛砖引玉吧,欢迎大家多多提意见。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • vue多种弹框的弹出形式的示例代码

    1.父组件引入子组件,子组件的加载问题 products.vue引入dlAddProd弹框(dlAddProd.vue),由于<div v-show="visible">,所以在products页面加载时,dlAddProd会被加载.但是el-dialog中的body部分不会被加载(不管有没有加v-if指令):dlAddProd弹框中又引入了dlBlankAdd弹框和dlEditProd弹框,但此时只有dlBlankAdd会被加载,dlEditProd不会被加载(<d

  • 详解用vue编写弹出框组件

    前言 最近研究了用vue编写弹出框的组件,发现其实这里面的门道还是有很多的.这篇文完全是用来记录总结下最近的学习成果,同时也希望能够帮得上正在学习纠结的你~ps:本文假设你已经了解vue2.0相关框架,因此适合有一定vue2.0基础的同学阅读. 设计组件的思考 其实单纯的编写一个弹出框组件并不难,写一个模板,然后用v-if或者v-show指令还控制组件的出现与消失.真正困扰我的是,这个组件的调用方式,这个问题纠结了我好久. 调研了下资料,有些人建议,直接把组件标签插进模板中,然后通过直接控制组件

  • 使用vue实现各类弹出框组件

    简单介绍一下vue中常用dialog组件的封装: 实现动态传入内容,实现取消,确认等回调函数. 首先写一个基本的弹窗样式,如上图所示. 在需要用到弹窗的地方中引入组件: import dialogBar from './dialog.vue' components:{ 'dialog-bar': dialogBar, }, <dialog-bar></dialog-bar> 点击一个按钮显示弹窗,并保证关闭弹窗后再次点击依旧显示 在弹窗组件中定义一个value值:v-model=&

  • vue弹出框组件封装实例代码

    新学vue,参考别人封装弹出层组件.好用! 1.你需要先建一个弹出框的模板: //首先创建一个mack.vue <template> <div class="mack" v-if="isShow"> <div class="mackWeb" :style="text.mackStyle"> <div class="title font_b" v-if="t

  • 详解基于Vue cli开发修改外部组件Vant默认样式

    前言 在引入外部组件的时候,想要修改默认样式,可以通过class修改,但一般会有权重不够等各种原因,官网其实列出了一套主题定制的方案,通过覆盖配置文件来修改样式,官网地址:主题定制 提示:以下是本篇文章正文内容,下面案例可供参考 一.Less 因为Vant 使用了 Less 对样式进行预处理,并内置了一些样式变量,可以通过替换样式变量即可定制你自己需要的主题. 给你的项目配置less: npm install less --save-dev npm install less-loader --s

  • 前端js弹出框组件使用方法

    下面分享一个js 弹出窗, 分 toast , dialog , load 三种弹窗 , 下面用js css 来实现以下: 首先是js代码 | 采用了 es6 的写法 //公共弹窗加载动画 const DIALOG_TOAST = '1', DIALOG_DIALOG = '2', DIALOG_LOAD = '3', class Dialog { constructor(type = DIALOG_DIALOG, dialogContent = '请求失败', wrapClassName =

  • vue组件实现弹出框点击显示隐藏效果

    本文实例为大家分享了vue实现弹出框点击显示隐藏的具体代码,供大家参考,具体内容如下 效果如下图 由于我的更改密码弹出框是一个组件引用的,所以在一开始是隐藏的,这就需要在当前的页面上对弹出框组件设置v-show,但是在弹出框显示出来的时候,操作执行完后当前页面的更改按钮已经被弹出框覆盖了.所以只能在弹出页面点击取消实现关闭隐藏弹出框.这样就需要写两个点击事件,但是两个点击事件就会有冲突,需要点击两下才能使弹出框显示和隐藏.然后我就用的以下方法,希望可以帮到大家!!! 代码如下 1.在当前页面中(

  • vue如何实现简易的弹出框

    目录 vue实现弹出框 1.Template 2.script => data 中定义 3.script => methods 中定义关闭方法 4.样式 vue实现弹窗选择 1.创建一个ImproveResume.vue 2.创建PickerPopup.vue组件 vue实现弹出框 说明:点击查询弹出模态,单击表格选中,点击模态外取消模态显示效果. 如图: 1.Template  <!-- 模态 - 选择人员 -->     <div class="model&qu

  • 基于Vue.js+Nuxt开发自定义弹出层组件

    今天给大家分享VPopup 基于Vue.js构建的轻量级移动端弹出框组件,详情如下所示: 一款融合了Vant.NutUI等热门Vue组件库中的Popup弹层.Dialog对话框.Toast提示框.ActionSheet动作面板框.Notify通知框等功能. 快速使用 在main.js中引入组件 // 引入弹窗Popup import Popup from './components/popup' Vue.use(Popup) 支持如下两种 组件式 及 函数式 调用插件. 组件式 <templat

  • Bootstrap实现提示框和弹出框效果

    首先讲一讲提示框(Tooltip) 的使用方法 样式文件: LESS版本:对应源文件 tooltips.less <style id="jsbin-css"> body { padding: 100px; } .btn { margin: 20px 10px 20px; } </style> </head> <body> <h3>按钮做的提示框</h3> <button type="button&q

  • JS组件Bootstrap实现弹出框和提示框效果代码

    前言:对于Web开发人员,弹出框和提示框的使用肯定不会陌生,比如常见的表格新增和编辑功能,一般常见的主要有两种处理方式:行内编辑和弹出框编辑.在增加用户体验方面,弹出框和提示框起着重要的作用,如果你的系统有一个友好的弹出提示框,自然能给用户很好的页面体验.前面几章介绍了bootstrap的几个常用组件,这章来看看bootstrap里面弹出框和提示框的处理.总的来说,弹出提示主要分为三种:弹出框.确定取消提示框.信息提示框.本篇就结合这三种类型分别来介绍下它们的使用. 一.Bootstrap弹出框

随机推荐