前端开发Vue3.0 标签setup语法『UI组件库』之『模态框』【业务提升必备】

 封装模态框需要定义的参数

  title //弹窗标题
  show   // 是否显示弹窗
  width  // 弹窗宽度
  height  // 弹窗高度
  borderRadius   // 弹窗圆角
  headerColor // 弹窗顶部颜色
  contentText // 内容文本
  contentTextCorder //内容文本颜色
  position // 标题的位置
  btnGroupShow // 按钮的显示隐藏
  confirmText // 确认按钮的文本
  cancelText // 取消按钮的文本

封装模态框需要定义的方法

const cancelHandler = () => {
    // 关闭弹窗的方法
}

const confirmHandler = () => {
   // 弹窗点击确认的方法
}

在components文件新建一个modal-dialog.vue文件

1、defineProps 在Vue 3中,defineProps 是一个用于定义传入组件的 Props 的函数。它通常用在组合式 API 或 Composition API 中。

2、defineEmits 的用法 defineEmits的用法是在子组件中定义接收父组件传过来的方法

<template>
  <div class="modal-box" v-if="show">
    <div class="dialog-box" :style="{
      'background-color':props.contentTextCorder,
      'border-radius':props.borderRadius + 'px',
      'text-align': props.position,
      'width':props.width + 'px',
      'height':props.height + 'px'
    }">
      <header
      :style="{
       'background-color':headerColor,
       'border-top-left-radius':props.borderRadius + 'px',
        'border-top-right-radius':props.borderRadius + 'px',
      }">
        <text>{
   
   {props.title}}</text>
      </header>
      <div class="icon" @click="cancelHandler">X</div>
      <div class="content">
         <p v-if="props.contentText" :style="{
           'color':props.contentTextCorder
         }">
           {
   
   {props.contentText}}
         </p>
        <slot name="content"></slot>
      </div>
      <footer>
        <div class="btn-box">
          <button v-if="props.btnGroupShow" class="boom" @click="cancelHandler">{
   
   {props.cancelText }}</button>
          <button v-if="props.btnGroupShow" class="boom" @click="confirmHandler">{
   
   {props.confirmText }}</button>
        </div>
      </footer>
    </div>
  </div>
</template>

<script setup>
import {defineProps,defineEmits} from "vue";
const emit = defineEmits(['confirm','close'])
const props = defineProps({
  //弹窗标题
  title:{
    type:String,
    default:'弹窗标题'
  },
  // 是否显示弹窗
  show:{
    type:Boolean,
    default:false
  },
  // 弹窗宽度
  width:{
    type:Number,
    default:500
  },
  // 弹窗高度
  height:{
    type:Number,
    default:200
  },
  // 弹窗圆角
  borderRadius:{
    type:Number,
    default:20
  },
  // 弹窗顶部颜色
  headerColor:{
    type:String,
    default:'blue'
  },
  // 内容文本
  contentText:{
    type:String,
    default:null
  },
  contentTextCorder:{
    type:String,
    default:'#fff'
  },
  position:{
    type:String,
    default:'center'
  },
  btnGroupShow:{
    type:Boolean,
    default:true
  },
  confirmText:{
    type:String,
    default:'是'
  },
  cancelText:{
    type:String,
    default:'否'
   }
})

const cancelHandler = () => {
  emit('close')
}

const confirmHandler = () => {
  emit('confirm')
}

</script>

<style scoped>

.modal-box{
  width: 100%;
  height: 100%;
  position: fixed;
  left: 0;
  top: 0;
  background-color: rgb(0,0,0,0.4);
}
.modal-box .dialog-box{
  background-color: #fff !important ;
  position: relative;
  left: 50%;
  top: 20%;
  transform: translate(-50%,-20%);
}
.icon{
  position: absolute;
  top: 10px;
  right: 15px;
  background-color: #ec6a5d;
  border-radius: 50%;
  width: 20px;
  height: 20px;
  text-align: center;
  color: #464444;
  font-size: 10px;
  line-height: 20px;
}
.icon:hover{
  cursor: pointer;
}
header{
  width: 100%;
  height: 40px;
  line-height: 40px;
  padding:0 10px 0 10px;
  box-sizing: border-box;
}
footer{
  width: 100%;
  height: 40px;
  position: absolute;
  left: 0;
  bottom: 0;
  display: flex;
  justify-content: flex-end;
  border-top: 1px solid #ccc;
}
footer .btn-box {
  width: 25%;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: space-around;
}
footer .btn-box button {
  height: 26px;
}
.content{
  width: 100%;
  padding:0 10px 0 10px;
  box-sizing: border-box;
}
button{
  border: 0;
  border-radius: 5%;
  cursor: pointer;
}

.boom {
  background-color: #16a085;
  color: #fff;
  position: relative;
  z-index: 1;
}

.boom::before {
  content: "";
  position: absolute;
  z-index: -1;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  border: 2px solid #16a085;
  border-radius: 20px;
  transform-origin: center;
}

.boom:hover::before {
  transform: scale(1.25);
  transition: all ease-out .5s;
  border: 1px solid #96f3e0;
  opacity: 0;
}


</style>

index.vue主组件

<template>
   <div>
     <ul>
       <li>
         3243243242343243243242
       </li>
       <li>
         3243243242343243243242
       </li>
       <li>
         3243243242343243243242
       </li>
     </ul>
     <button @click="openDialog">打开弹窗</button>
     <modal-dialog
      :title="title"
      :show="isShow"
      :width="500"
      :height="200"
      :borderRadius="10"
      headerColor="skyblue"
      contentText="This is a super modal this is a super madel"
      contentTextCorder="red"
      position="left"
      :btnGroupShow="true"
      confirmText="确定"
      cancelText="取消"
      @confirm="modalConfirm"
      @close="modalClose"
     >
       <template v-slot:content>
         <h3>我是具名插槽</h3>
       </template>
     </modal-dialog>
   </div>
</template>

<script setup>
// 引入组件不用注册
import modalDialog from './components/modal-dialog.vue'

import {ref} from 'vue'
const title = ref('我是弹窗')
const isShow = ref(false)

// 弹窗的确认事件

const modalConfirm = () => {
  isShow.value = false
}

// 弹窗的关闭事件

const modalClose = () => {
  isShow.value = false
}


const openDialog = () => {
  isShow.value = true
}

</script>

<style>
a{
  color: skyblue;
}
</style>

猜你喜欢

转载自blog.csdn.net/qq_54753561/article/details/131984900