用Vue.extend写一个全局使用的Alert

由于项目中经常会用到alert这种组件,平常都是全局注册标签,使用时引入,比较繁琐;
<!–more–>

借鉴别人这种组件一般是在js中被调用,vue中组件主要是使用了标签的形式,
现记录通过Vue.extend实现的动态组件;
Vue-extend官方文档

项目预览

<iframe src=”https://codesandbox.io/embed/…; title=”弹窗组件” allow=”geolocation; microphone; camera; midi; vr; accelerometer; gyroscope; payment; ambient-light-sensor; encrypted-media” style=”width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;” sandbox=”allow-modals allow-forms allow-popups allow-scripts allow-same-origin”></iframe>

Alert开发

项目目录

  • components

    • alert

      • alert.vue
      • index.js
    • HelloWord.vue
  • main.js

alert.vue

  • template部分
<template>
  <div class="shade">
    <div class="mian">
      <div class="content">
        <span>{{ message }}</span>
      </div>
      <div class="btns">
        <div class="btn"
             v-for="(btn,index) in btns"
             :key="index"
             @click="(e)=>clickFn(e,btn)">{{btn.text}}</div>
      </div>
    </div>
  </div>
</template>
  • JavaScript部分
export default {
  name: "alert",
  data () {
    return {
      message: "this a alert",
      btns: [
        {
          text: "yes",
          click: () => console.log('yes')
        },
        {
          text: "no",
          click: () => console.log('yes')
        }
      ]
    };
  },
  methods: {
    clickFn (event, btn) {
      this.$el.remove(); // 移除DOM
      const {
        click = () => console.warn("请传入回调函数")
      } = btn;
      click(event, btn); // 传递回去
    }
  }
};
  • css部分
.shade {
  user-select: none;
  width: 100vw;
  height: 100vh;
  position: fixed;
  top: 0;
  left: 0;
  background-color: rgba(0, 0, 0, 0.03);
  z-index: 998;
  display: flex;
  align-items: center;
  justify-content: center;
}
.shade .mian {
  background: white;
  width: 80%;
  border-radius: 5px;
  overflow: hidden;
  box-shadow: 0px 0px 5px 3px rgba(0, 0, 0, 0.04);
  box-sizing: border-box;
  animation: open 0.1s;
}
.shade .mian .content {
  box-sizing: border-box;
  width: 100%;
  padding: 30px 20px;
}
.shade .mian .btns {
  height: 45px;
  box-sizing: border-box;
  border-top: 1px solid rgba(0, 0, 0, 0.1);
  display: flex;
  justify-content: space-around;
  align-items: center;
}
.shade .mian .btns .btn {
  flex: 1 0 auto;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  border-right: 1px solid rgba(0, 0, 0, 0.1);
}
.shade .mian .btns .btn:last-child {
  border-right: none;
}
.shade .mian .btns .btn:active {
  color: white;
  background-color: rgb(64, 169, 243);
}
@keyframes open {
  0%,
  100% {
    transform: scale(1);
  }
  25%,
  75% {
    transform: scale(1.04);
  }
  50% {
    transform: scale(1.06);
  }
}

index.js

import Vue from 'vue';
import alert from './alert.vue';
let MyAlertConstructor = Vue.extend(alert);
let instance;
const MyAlert = (option) => {
  // 创建实例并且过滤参数
  instance = new MyAlertConstructor({
    data: { ...option }
  })
  // 挂载实例
  instance.$mount();
  document.body.appendChild(instance.$el);
  return instance;
}
// 挂载到Vue原型上
Vue.prototype.$alert = MyAlert;

main.js

import './components/alert'; // 引入注册一下

到这里我们的Alert组件就配置完成了;

如何使用

这里我在 Helloword.vue 中测试使用;

export default {
  name: "HelloWorld",
  props: {
    msg: String
  },
  methods: {
    Alert() {
      //  使用直之前绑定到原型上的方法
      this.$alert({
        message: "你今天开心吗?",
        btns: [
          {
            text: "开心",
            click: () => {
              // 测试是否可以拿到这边的this
              console.log(this.msg);
            }
          },
          {
            text: "不开心",
            click: (e, btn) => {
              // 这里的event target 可能没用 因为已经移除DOM了
              // 返回btn原来本身
              console.log("不开心", e, btn);
            }
          },
          {
            text: "无回调"
            // 测试一下没有回调函数的时候
          },
          {
            text: "帮助",
            click: this.isOK
          }
        ]
      });
    },
    isOK() {
      console.log("输出帮助");
    }
  }};

项目截图

《用Vue.extend写一个全局使用的Alert》

参考文档

    原文作者:吴小红
    原文地址: https://segmentfault.com/a/1190000019945047
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞