Vue2 移动端(H5)项目封装弹窗组件

前言

vant-uidialog组件没有自定义footer插槽

效果

参数配置

1、代码示例:

html 复制代码
<t-dialog :visible.sync="show" :title="title" @submit="submit"></t-dialog>

2、配置参数(t-dialog Attributes)

参数 说明 类型 默认值
visible 是否显示弹窗 (必须加.sync 修饰符) Boolean false
title 弹窗标题 String '-
width 弹窗宽度 String 351px
height 弹窗高度 String auto
cancelButtonText 取消按钮文字 String 取消
confirmButtonText 确定按钮文字 String 确定
showCancelButton 是否显示取消按钮 Boolean true
showConfirmButton 是否显示确定按钮 Boolean true
isShowHeader 是否显示头部 Boolean true
isShowMask 是否显示遮罩层 Boolean true
isClickMaskClose 是否点击遮罩关闭弹窗 Boolean true
isCloseMask 是否显示标题右侧关闭icon Boolean true
footer 是否显示底部操作按钮(:footer="null") Object -

3、events 事件

事件名 说明 返回值
submit 点击确定按钮 -

4、slot 插槽

事件名 说明 返回值
title title插槽 -
- 默认内容区域插槽 -
footer 操作按钮插槽 -

三、源码

html 复制代码
<template>
  <div class="t_dialog" v-if="isShow">
    <div class="dialog_content" :style="{width: width, height: height}">
      <div class="header_title" v-if="isShowHeader">
        {{ title }}
        <slot name="title" />
        <van-icon @click="closePopup" v-if="isCloseMask" name="cross" />
      </div>
      <div class="content">
        <slot />
      </div>
      <div
        class="footer"
        :class="{'footer-no-button': !showCancelButton||!showConfirmButton, 'footer-null': (!showCancelButton&&!showConfirmButton)}"
        v-if="(footer!==null)"
      >
        <slot name="footer" />
        <template v-if="!$slots.footer">
          <van-button @click="closePopup" v-if="showCancelButton">{{cancelButtonText}}</van-button>
          <van-button type="danger" @click="submit" v-if="showConfirmButton">{{confirmButtonText}}</van-button>
        </template>
      </div>
    </div>
    <div class="dialog-mask" v-if="isShowMask" @click="closeMask"></div>
  </div>
</template>
<script>
export default {
  name: 'TDialog',
  props: {
    // 是否显示弹窗
    visible: {
      type: Boolean,
      default: false
    },
    // 弹窗标题
    title: {
      type: String,
    },
    width: {
      type: String,
      default: '351px'
    },
    height: {
      type: String,
      default: 'auto'
    },
    // 取消按钮文字
    cancelButtonText: {
      type: String,
      default: '取消'
    },
    // 确定按钮文字
    confirmButtonText: {
      type: String,
      default: '确定'
    },
    // 是否显示取消按钮
    showCancelButton: {
      type: Boolean,
      default: true
    },
    // 是否显示确定按钮
    showConfirmButton: {
      type: Boolean,
      default: true
    },
    // 是否显示头部
    isShowHeader: {
      type: Boolean,
      default: true
    },
    // 是否显示遮罩层
    isShowMask: {
      type: Boolean,
      default: true
    },
    // 是否点击遮罩关闭弹窗
    isClickMaskClose: {
      type: Boolean,
      default: true
    },
    // 是否显示关闭按钮
    isCloseMask: {
      type: Boolean,
      default: true
    },
    // 是否显示底部操作按钮 :footer="null"
    footer: Object,
  },
  computed: {
    isShow: {
      get() {
        return this.visible
      },
      set(val) {
        this.$emit('update:visible', val)
      }
    }
  },
  methods: {
    closePopup() {
      this.isShow = false
    },
    closeMask() {
      if (!this.isClickMaskClose) return
      this.isShow = false
    },
    submit() {
      this.$emit('submit')
      // this.isShow = false
    }
  },

}
</script>
<style lang="scss" scoped>
.t_dialog {
  .dialog_content {
    position: fixed;
    top: 50%;
    left: 50%;
    -webkit-transform: translate3d(-50%, -50%, 0);
    transform: translate3d(-50%, -50%, 0);
    max-width: 100%;
    max-height: 100%;
    background-color: #fff;
    z-index: 1000;
    border-radius: 8px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.7);
  }
  .header_title {
    height: 40px;
    padding: 0 20px;
    font-size: 16px;
    color: #101010;
    background: #fff;
    border-bottom: 1px solid #e5e5e5;
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
    border-radius: 8px 8px 0 0;
    .van-icon {
      cursor: pointer;
      position: absolute;
      right: 20px;
      top: 50%;
      -webkit-transform: translateY(-50%);
      transform: translateY(-50%);
      font-size: 16px;
      color: #999;
      &:hover {
        color: #333;
      }
    }
  }
  .content {
    padding: 15px;
    width: calc(100% - 30px);
    overflow-y: auto;
  }
  .footer {
    height: 40px;
    line-height: 40px;
    color: #101010;
    background: #fff;
    border-top: 1px solid #e5e5e5;
    display: flex;
    justify-content: space-between;
    align-items: center;
    position: relative;
    border-radius: 0 0 8px 8px;
    button {
      flex: 0 50%;
      height: 40px;
      line-height: 40px;
      padding: 0;
      font-size: 16px;
      border: none;
      border-radius: 0 0 8px 0px;
      &:first-child {
        border-right: 1px solid #e5e5e5;
        border-radius: 0 0 0px 8px;
      }
    }
    .van-button--primary {
      color: #007aff;
      border: none;
      background-color: #fff;
    }
    .van-button--danger {
      color: #ff4444;
      border: none;
      background-color: #fff;
    }
    &.footer-no-button {
      button {
        flex: 0 auto;
        border: none;
        border-radius: 0 0 8px 8px;
        width: 100%;
      }
    }
    &.footer-null {
      display: none;
    }
  }
  .dialog-mask {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: #000;
    opacity: 0.7;
    z-index: 999;
  }
}
</style>

相关文章

基于ElementUi再次封装基础组件文档


基于ant-design-vue再次封装基础组件文档


vue3+ts基于Element-plus再次封装基础组件文档

相关推荐
Mh1 小时前
听说我兄弟喜欢跑车,所以必须安排上
前端·javascript·vue.js
zttbee1 小时前
vue学习(白话功能版)
前端·vue.js·学习·前端框架
nicole bai1 小时前
前端封装el-table及注意点
前端·javascript·vue.js
晨枫阳1 小时前
Vue 前端构建工具链完全理解指南
前端·javascript·vue.js
ly768918 小时前
Vue 3 从入门到工程实践:基础语法、组件化、路由、状态管理与项目部署
前端·javascript·vue.js
梅孔立20 小时前
Pi-Agent 终极极简配置文档(Java+Vue+Python爬虫 4-5千文件项目)
java·vue.js·python
码视野1 天前
基于 Vue3 + Element Plus 的【智慧社区洗车养车与上门流动洗车预约调度系统】设计与实现(含PRD/三端源码/大屏)
前端·javascript·vue.js·人工智能·vue3
码视野1 天前
基于 Vue3 + Element Plus 的【无人值守共享自习室与空间智能预约系统】设计与实现(含PRD/三端源码/大屏)
前端·javascript·vue.js·人工智能·vue3
Su米苏1 天前
针对使用@vue-office 出现的包异常找不到问题
前端·javascript·vue.js
用户83134859306981 天前
Cesium实现动态流动火烧云晚霞效果(可用slider调整火烧云浓度)
vue.js·webgl·cesium