• vue2.0 自定义 弹窗(MessageBox)组件


    组件模板

    src/components/MessageBox/index.vue

    <!-- 自定义 MessageBox 组件 -->
    <template>
      <div class="message-box" v-show="isShowMessageBox">
        <div class="mask" @click="cancel"></div>
        <div class="message-content">
          <svg class="icon" aria-hidden="true" @click="cancel">
            <use xlink:href="#icon-delete"></use>
          </svg>
          <h3 class="title">{{ title }}</h3>
          <p class="content">{{ content }}</p>
          <div>
            <input type="text" v-model="inputValue" v-if="isShowInput" ref="input" @keyup.enter="confirm">
          </div>
          <div class="btn-group">
            <button class="btn-default" @click="cancel" v-show="isShowCancelBtn">{{ cancelBtnText }}</button>
            <button class="btn-primary btn-confirm" @click="confirm" v-show="isShowConfimrBtn">{{ confirmBtnText }}</button>
          </div>
        </div>
      </div>
    </template>
    
    <script>
      export default {
        props: {
          title: {
            type: String,
            default: '标题'
          },
          content: {
            type: String,
            default: '这是弹框内容'
          },
          isShowInput: false,
          inputValue: '',
          isShowCancelBtn: {
            type: Boolean,
            default: true
          },
          isShowConfimrBtn: {
            type: Boolean,
            default: true
          },
          cancelBtnText: {
            type: String,
            default: '取消'
          },
          confirmBtnText: {
            type: String,
            default: '确定'
          }
        },
        data () {
          return {
            isShowMessageBox: false,
            resolve: '',
            reject: '',
            promise: '' // 保存promise对象
          };
        },
        methods: {
          // 确定,将promise断定为resolve状态
          confirm: function () {
            this.isShowMessageBox = false;
            if (this.isShowInput) {
              this.resolve(this.inputValue);
            } else {
              this.resolve('confirm');
            }
            this.remove();
          },
          // 取消,将promise断定为reject状态
          cancel: function () {
            this.isShowMessageBox = false;
            this.reject('cancel');
            this.remove();
          },
          // 弹出messageBox,并创建promise对象
          showMsgBox: function () {
            this.isShowMessageBox = true;
            this.promise = new Promise((resolve, reject) => {
              this.resolve = resolve;
              this.reject = reject;
            });
            // 返回promise对象
            return this.promise;
          },
          remove: function () {
            setTimeout(() => {
              this.destroy();
            }, 300);
          },
          destroy: function () {
            this.$destroy();
            document.body.removeChild(this.$el);
          }
        }
      };
    </script>
    
    <style lang="less" scoped>
      .message-box {
        position: relative;
        .mask {
          position: fixed;
          top: 0;
          left: 0;
          bottom: 0;
          right: 0;
          z-index: 50000;
          background: rgba(0, 0, 0, 0.5);
        }
        .message-content {
          position: fixed;
          box-sizing: border-box;
          padding: 1em;
          min- 90%;
          left: 50%;
          top: 50%;
          transform: translate(-50%, -50%);
          border-radius: 0.4em;
          background: #fff;
          z-index: 50001;
          .icon {
            position: absolute;
            top: 1em;
            right: 1em;
             0.9em;
            height: 0.9em;
            color: #878d99;
            cursor: pointer;
            &:hover {
              color: #2d8cf0;
            }
          }
          .title {
            font-size: 1.2em;
            font-weight: 600;
            margin-bottom: 1em;
          }
          .content {
            font-size: 1em;
            line-height: 2em;
            color: #555;
          }
          input {
             100%;
            margin: 1em 0;
            background-color: #fff;
            border-radius: 0.4em;
            border: 1px solid #d8dce5;
            box-sizing: border-box;
            color: #5a5e66;
            display: inline-block;
            font-size: 14px;
            height: 3em;
            line-height: 1;
            outline: none;
            padding: 0 1em;
            &:focus {
              border-color: #2d8cf0;
            }
          }
          .btn-group {
            margin-top: 1em;
            float: right;
            overflow: hidden;
            .btn-default {
              padding: 0.8em 1.5em;
              font-size: 1em;
              color: #555;
              border: 1px solid #d8dce5;
              border-radius: 0.2em;
              cursor: pointer;
              background-color: #fff;
              outline: none;
    
              &:hover {
                color: #2d8cf0;
                border-color: #c6e2ff;
                background-color: #ecf5ff;
              }
            }
    
            .btn-primary {
              padding: 0.8em 1.5em;
              font-size: 1em;
              color: #fff;
              border-radius: 0.2em;
              cursor: pointer;
              border: 1px solid #2d8cf0;
              background-color: #2d8cf0;
              outline: none;
    
              &:hover {
                opacity: .8;
              }
            }
            .btn-confirm {
              margin-left: 1em;
            }
          }
        }
      }
    </style>
    

    给组件添加全局功能

    src/components/MessageBox/index.js

    import msgboxVue from './index.vue';
    
    // 定义插件对象
    const MessageBox = {};
    // vue的install方法,用于定义vue插件
    MessageBox.install = function (Vue, options) {
      const MessageBoxInstance = Vue.extend(msgboxVue);
      let currentMsg;
      const initInstance = () => {
        // 实例化vue实例
        currentMsg = new MessageBoxInstance();
        let msgBoxEl = currentMsg.$mount().$el;
        document.body.appendChild(msgBoxEl);
      };
      // 在Vue的原型上添加实例方法,以全局调用
      Vue.prototype.$msgBox = {
        showMsgBox (options) {
          if (!currentMsg) {
            initInstance();
          }
          if (typeof options === 'string') {
            currentMsg.content = options;
          } else if (typeof options === 'object') {
            Object.assign(currentMsg, options);
          }
          return currentMsg.showMsgBox()
            .then(val => {
              currentMsg = null;
              return Promise.resolve(val);
            })
            .catch(err => {
              currentMsg = null;
              return Promise.reject(err);
            });
        }
      };
    };
    
    export default MessageBox;
    

    全局使用

    src/main.js

    import MessageBox from './components/MessageBox/index';
    Vue.use(MessageBox);
    

    页面调用

    test.vue

    <!-- 弹窗 -->
    <template>
      <div>
        <!-- 标题栏 -->
        <mt-header title="弹窗">
          <router-link to="/" slot="left">
            <mt-button icon="back">返回</mt-button>
          </router-link>
        </mt-header>
      </div>
    </template>
    
    <script>
      export default {
        name: 'MessageBox',
        data(){
          return {
            //
          }
        },
        mounted(){
          this.$msgBox.showMsgBox({
              title: '添加分类',
              content: '请填写分类名称',
              isShowInput: true
          }).then(async (val) => {
              console.log(val);
          }).catch(() => {
              // ...
          });
        },
      }
    </script>
    
    <style lang="less" scoped>
      //
    </style>
    

    效果图

  • 相关阅读:
    java中==和equels的区别
    synchronized的用法及原理
    分库分表之Mycat实现
    Mysql架构和索引及性能优化
    Java内存模型与反向代理服务器Nginx
    Spring基础知识
    使用和理解线程池
    知识补充(数据库优化、三大范式)
    最大子数组问题,分治法求解
    Mybatis学习笔记
  • 原文地址:https://www.cnblogs.com/crazycode2/p/7907905.html
Copyright © 2020-2023  润新知