十五分钟两百行代码,手写一个vue项目全局通用的弹框

前言:

我们在写vue项目时,弹框是非常常用的组件,并且在同一个项目中,弹框大多类似。所以我们可以抽离封装出一个通用的弹框;

因为vue3可向下兼容,所以作者这边会使用vue2的写法,vue3写法大同小异。

第一步:新建相关文件

一般来说是在src/components/dialog下新建如下两个文件:

  1. index.vue:该文件是组件内容相关的,用来书写弹框组件的结构、样式、和动态逻辑;
  2. index.js:该文件使用虚拟节点创建组件内容,并且注册组件。

第二步:书写组件内容

index.vue组件内容如下:

  1. 结构 + js 代码
<template>   <div class="default-message" :id="boxId">     <div class="default-message-content">       <div class="default-message-title">{{ title }}</div>       <div class="default-message-value" v-html="message"></div>       <div class="default-message-btns">         <div           class="default-message-cancle default-message-btn"           v-if="cancelBtnHtml"           @click.prevent.stop="handleCancel"         >           {{ cancelBtnHtml }}         </div>         <div           class="default-message-submit default-message-btn"           @click.prevent.stop="handleOk"         >           {{ okBtnHtml }}         </div>       </div>     </div>   </div> </template>  <script> import i18n from "@/i18n"; import { defineComponent } from "vue"; export default defineComponent({   name: "Dialog",   data() {     return {       i18nTitle: '',       i18nOkBtn: '',     };   },   props: {     boxId: {       type: String,       default: "",     },     // 标题     title: {       type: String,       default: "",     },     // 内容     message: {       type: String,       default: "",     },     // 确定按钮文字     okBtnHtml: {       type: String,       default: '',     },     // 取消按钮文字     cancelBtnHtml: {       type: String,       default: "",     },     // 成功回调     ok_function: {       type: Function,     },     // 失败回调     cancel_function: {       type: Function,     },   },   methods: {     handleCancel() {       this.removeModal();       this.cancel_function && this.cancel_function();     },     handleOk() {       this.removeModal();       this.ok_function && this.ok_function();     },     removeModal() {       const modelDom = document.getElementById(         "__default__container__content__"       );       if (modelDom) {         document.body.removeChild(modelDom);       }     },   },   created() {     this.i18nTitle = i18n.global.t('modal_warm_tip_title');     this.i18nOkBtn = i18n.global.t('activity_ok');   }, }); </script>  

结构说明:

  • .default-message使我们整个弹框的容器,一般宽高都设置为100%,这个部分会有一个半透明的背景色(覆盖页面内容,防止弹框了还能操作页面);
  • .default-message-content为整个弹框的内容区域,包括标题、提示信息、取消按钮、确定按钮;
  • 取消按钮和确定按钮支持执行传入的事件,方便我们在弹框弹出后点击按钮执行相应操作;
  1. 样式
<style lang="less" scoped> .default-message {   position: fixed;   right: 0;   top: 0;   bottom: 0;   left: 0;   width: 100%;   height: 100%;   z-index: 1000;   background: rgba(0, 0, 0, 0.7);    .default-message-title {     color: #333;     margin: 0;     line-height: 1.5;     font-size: 18px;     min-height: 18px;     padding-top: 20px;     text-overflow: ellipsis;     font-weight: bold;     cursor: move;     text-align: center;   }    .default-message-content {     width: 85%;     position: absolute;     top: 50%;     left: 50%;     transform: translate3d(-50%, -50%, 0);     background-color: #fff;     border-radius: 6px;     transition: all 0.2s ease-in;     color: #999;     font-size: 18px;   }    .default-message-value {     padding: 28px 18px;     text-align: center;     position: relative;     color: #999;     text-align: center;     font-size: 14px;     color: rgba(102, 102, 102, 1);   }   .default-message-btns {     // border-top: 1px solid #ddd;     display: flex;     height: 60px;     position: relative;     &:after {       position: absolute;       content: "";       display: inline-block;       left: 0;       right: 0;       top: 0;       height: 1px;       transform: scaleY(0.5);       background: #ddd;     }     .default-message-btn {       flex: 1;       display: flex;       align-items: center;       justify-content: center;       font-size: 16px;       padding: 0 3px;     }     .default-message-submit {       color: #26a2ff;     }     .default-message-cancle {       color: #999;       position: relative;       &:after {         position: absolute;         content: "";         display: inline-block;         top: 0;         right: 0;         bottom: 0;         width: 1px;         transform: scaleX(0.5);         background: #ddd;       }     }   }   @keyframes fadeIn {     from {       opacity: 0;     }     to {       opacity: 1;     }   } } </style> 

第三步:注册成全局组件

import {createVNode, render} from 'vue'; import MessageConstructor from './index.vue';  const $dialog = function (options) {   // 已存在一个弹窗则不重复渲染   if (!document.getElementById ('__default__container__content__')) {     // 创建div     const container = document.createElement ('div');     // container.className = `__default__container__message__`;     container.id = '__default__container__content__';     //创建虚拟节点     const vm = createVNode (MessageConstructor, options);     //渲染虚拟节点     render (vm, container);     document.body.appendChild (container);   } };  export default {   //组件注册   install (app) {     app.config.globalProperties.$dialog = $dialog;   }, };  

到这里,我们的弹框组件就完成了,接下来我们来使用看看。

项目中使用弹框

使用的方法也非常简单,所见即所得。

app.config.globalProperties.$dialog({   title: "弹框标题",   message: "弹框提示信息文案",   okBtnHtml: "确定",   cancelBtnHtml: "取消",   ok_function: () => {     console.log("点击弹框确定按钮处理函数");   },   cancel_function: () => {     console.log("点击弹框取消按钮处理函数");   } }); 

说明:

  1. 标题、提示文案、以及取消和确定按钮文案,我们这边直接传入,ok_function是确定按钮的回调,我们可以在这里做任何点击确定后想做的事,包括发送请求和异步操作,cancel_function同理。
  2. 弹框图片示例:

十五分钟两百行代码,手写一个vue项目全局通用的弹框

写在后面

这是一个比较基础的弹框组件,这边示例的代码是比较全的,对细节要求不大的小伙伴可以直接用;

背景颜色、字体、布局等这些细节,因为每个业务场景不同,大家可以根据自己的需要适当调整;

弹框是固定单位的,如果小伙伴的项目需要使用响应式大小,直接对应替换大小单位即可;

对你有帮助的话给作者点点关注吧,你的支持是我不断更新的动力!Peace and love~~

发表评论

评论已关闭。

相关文章