利用vue的install开发一个简易全局注册的alert组件

首先新建一个alert组件

<template>
    <div class="layer-alert-bg">
        <div class="layer-alert">
            <div class="fj-title">{{ title }}
                <button class="fj-close" @click.stop="_closeCallback">X</button>
            </div>
            <div class="fj-content">
                {{ text }}
            </div>
            <div class="fj-btn" @click.stop="_btnCallback">
                <button>{{btnMessage}}</button>
            </div>
        </div>
    </div>
</template>

设置alert组件需要传入的属性以及方法 

    props: {
      title: {type: String,default: "温馨提示"},
      text: {type: String,default: ""},
      btnMessage: {type: String,default: "确定"},
      finallyCallback: {type: Function,default() {return function() {};}},
      btnCallback: {type: Function,default() {return function() {};}},
      closeCallback: {type: Function,default() {return function() {};}},
    }

添加alert组件的methods方法

    methods: {
      _closeCallback() {
        this.hide();
        this.closeCallback();
        this.finallyCallback(0);
      },
      _btnCallback() {
        const index =  this.btnCallback(); // 调用的时候,如果有返回值代表不可以关闭当前组件
        this.finallyCallback(1); // 不管点击了哪个按钮,都会运行这个方法
        if(typeof index === 'function'){
          this.hide();
          return;
        }
        if (index === undefined) {
          this.hide(); // ts文件里面定义的hide方法
        } else {
          console.log('关不掉哦'); // 不允许关闭弹出框
        }
      }
    }

 新建ts文件:

import AlertComponent from "./alert.vue";

interface Alert {
  title?: string;
  text: string;
  btnMessage?: string;
  finallyCallback?: (num: number | string) => void;
  btnCallback?: () => void | any;
  closeCallback?: () => void;
}

export const FjAlert = {
  install(Vue: any, options: Alert) {
    Vue.prototype.$alert = {
      show: (options: Alert) => {
        // 确保每次点击都会是独立的,要在调用show方法的时候创建
        let alertTmp = Vue.extend(AlertComponent); // 创建vue构造器
        let $vm = new alertTmp();//实例化vue实例
        
        document.body.appendChild($vm.$mount().$el); // 添加到浏览器body中
        if (typeof options === "string") {
          $vm.text = options; // 传入props
        } else if (typeof options === "object") {
          Object.assign($vm, options); // 合并参数与实例
        }
        // 关闭当前组件,在alert组件内部需要用到
        $vm.hide = () => {
          document.body.removeChild($vm.$mount().$el);
        };
        return $vm.$mount().$el; // 用来关闭组件的
      },
      hide: (ele: any) => {
        // 在页面中查找alert,如有还存在的话就移除掉
        const alertEles = document.querySelectorAll('.layer-alert-bg');
        alertEles.forEach(aele => {
          if(ele === aele){document.body.removeChild(ele);}
        });
      }
    }
  }
};

 最后在main.ts中use下:    Vue.use(FjAlert); // 很重要哦

这样我们的全局组件就完成啦,接下来我们来使用把:

// 可以直接传字符串
this.$alert.show("我是alert哦!");

// 也可以传入配置参数
const alertEle = this.$alert.show({
  title: "警告!",
  text: "黄鹤王八蛋老板带着他的小姨子跑了!",
  btnMessage: "打一顿!",
  btnCallback: () => {
    console.log("打吧");
    return false;
  },
  closeCallback: () => {
    console.log("求放过");
  },
  finallyCallback: (index) => {
    console.log(index === 0 ? "放过" : "打一顿");
  }
});

// 点击了"打一顿"按钮,阻止了alert组件关闭,调用下面的方法则可以关闭传入的的alert
this.$alert.hide(alertEle)

交互图如下(请忽略这丑丑的UI(✿◡‿◡)):

发布了112 篇原创文章 · 获赞 149 · 访问量 55万+

猜你喜欢

转载自blog.csdn.net/l284969634/article/details/103808944