通过vue.extend实现一个弹窗组件

论坛 期权论坛 编程之家     
选择匿名的用户   2021-6-2 15:49   3900   0

1.首先编写需要被继承的弹窗组件

<template>
  <div v-if="show" ref="modal" class="ek-modal_wrap">
    <div class="ek-modal-content">
      <div class="modal-title-wrap">
        <div class="modal-title">{{ title }}</div>
        <slot name="description"></slot>
      </div>
      <div class="modal-button">
        <a v-if="confirmVisible" class="contral-btn confirm-btn" href="javascript:;" @click="confirm">{{
          confirmText
        }}</a>
        <a v-if="cancleVisible" class="contral-btn cancle-btn" href="javascript:;" @click="cancle">{{ cancleText }}</a>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      show: true,
      title: '', // 标题
      confirmText: '确定', // 确认文字
      confirmVisible: true, // 是否展示确认按钮
      onConfirm: () => { // 确认执行函数
        this.$emit('confirm')
      }, 
      cancleText: '取消', // 取消文字
      cancleVisible: true, // 是否展示取消按钮
      onCancle: () => { // 取消执行函数
        this.$emit('cancle')
      } 
    }
  },
  methods: {
    confirm() {
      this.onConfirm()
      this.close()
    },
    cancle() {
      this.onCancle()
      this.close()
    },
    close() {
      this.show= false
      if (this.$refs.modal) {
        this.$refs.modal.remove() // 关闭时候直接移除当前元素
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.ek-modal_wrap {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 999;
  width: 100%;
  height: 100%;
  font-size: 28px;
  background: rgba(0, 0, 0, 0.7);
  .ek-modal-content {
    position: fixed;
    top: 50%;
    left: 50%;
    min-width: 7.2rem;
    overflow-x: hidden;
    overflow-y: hidden;
    text-align: center;
    background-color: white;
    border-top-left-radius: 0.266667rem;
    border-top-right-radius: 0.266667rem;
    border-bottom-right-radius: 0.266667rem;
    border-bottom-left-radius: 0.266667rem;
    transform: translate(-50%, -50%);
    .modal-title-wrap {
      display: flex;
      flex-direction: column;
      flex-grow: 1;
      justify-content: center;
      min-height: 55px;
      padding: 0 20px;
      color: #333;
    }
    .modal-title {
      display: flex;
      flex-direction: column;
      flex-grow: 1;
      justify-content: center;
      min-height: 100px;
      margin-top: 30px;
      margin-bottom: 30px;
      font-weight: 600px;
      line-height: 50px;
      color: #333;
    }
    .modal-button {
      display: flex;
      line-height: 1;
      color: #333;
      border-top-color: #e7e7e7;
      border-top-style: solid;
      border-top-width: 1px;
      & > a {
        color: #333;
      }
      .contral-btn {
        flex-basis: 0%;
        flex-grow: 1;
        flex-shrink: 1;
        font-weight: 600px;
        line-height: 3;
        text-align: center;
        &.cancle-btn {
          border-left-color: #e7e7e7;
          border-left-style: solid;
          border-left-width: 1px;
        }
      }
    }
  }
}
</style>

2.编写可以根据场景灵活使用的弹窗函数

import Vue from 'vue'
import Dialog from './Dialog'


function showModal(options) {

  const app = new Dialog().$mount(document.createElement('div')) // 创建组件实例并挂载 
  // 通过传入的参数,初始化弹窗参数

  for (let key in options) {

    app[key] = options[key]

  }
  // 最后将元素插入到body中

  document.body.appendChild(app.$el)

}

Vue.prototype.$showModal = showModal // 将方法设置在原型上,以便组件实例调用

3.最后在组件中调用方法

 this.$showModal({ title: '我是测试内容', confirmText: '知道了',onConfirm:() {
     // 执行点击确认的时候的方法
     console.log('被点击了')
    } ,cancleVisible: false })

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP