概述

当我们使用组件库的时候,某些组件并不是直接放到模板当中进行使用,而是通过api的方式调用生成组件并且挂在到我们的页面中,其中最常见的就是message组件,我们在组件库中看到的多数都是api调用的方式生成。记录自己基本实现message组件。

Vue.extend

在vue中,要实现通过api方式实现组件的使用,这个aip是必不可少的,因此我们先了解下这个全局api的用法,官网说的很晦涩难懂,我的理解就是通过参数传递一个配置对象(这个配置对象就是我们模板中export default的那个对象,例如data,methods,props等等)都可以传递,接下来该函数会根据我们的配置对象生成一个继承自Vue的子组件构造函数,然后我们就可以通过实例化构造函数,生成对应的组件,然后我们就可以挂载到页面了。

message 组件配置对象(就是.vue文件)

<template>
  <div
    :class="['message-box', 'message-box-' + type]"
    :style="{ top: top + 'px' }"
  >
    <header>
      <span class="close">X</span>
    </header>
    <div class="message--box-content">
      {{ message }}
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return {};
  },
  props: {
    message: {
      type: String,
      default: "this is message box",
    },
    type: {
      validator(value) {
        return ["success", "error", "default"].indexOf(value) !== -1;
      },
      default: "default",
    },
    top: {
      type: Number,
      default: 20,
    },
  },
};
</script>
<style lang="less">
.message-box {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  width: 400px;
  height: 50px;
  background-color: #ccc;
  .close {
    position: absolute;
    top: 0;
    right: 5px;
    cursor: pointer;
  }
  .message--box-content {
    line-height: 50px;
    text-indent: 2em;
  }
  &.message-box-success {
    background-color: green;
  }
  &.message-box-error {
    background-color: red;
  }
  &.message-box-default {
    background-color: #eee;
  }
}
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.5s;
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
  opacity: 0;
}
</style>

message 生成组件的函数

import MessageBoxOption from "./index.vue";
import Vue from "vue";
let messageBoxConstructor = Vue.extend({
  ...MessageBoxOption,
});
export default {
  install(Vue) {
    Vue.prototype.$Message = {
      instanceList: [],
      hide(types) {
        for (let instance of this.instanceList) {
          if (instance.types == types) {
            instance &&
              document.body.removeChild(instance.$el) &&
              Reflect.deleteProperty(this, types);
          }
        }
      },
      success(message) {
        if (!this.vmSuccess) {
          let messageBox = new messageBoxConstructor({
            propsData: {
              message,
              type: "success",
              top: (this.instanceList.length + 1) * 55,
            },
          });
          let $Message = messageBox.$mount();
          this.vmSuccess = $Message;
          this.instanceList.push({ ...$Message, types: "vmSuccess" });
          document.body.appendChild($Message.$el);
          setTimeout(() => {
            this.hide("vmSuccess");
          }, 4000);
        }
      },
      error(message) {
        if (!this.vmError) {
          let messageBox = new messageBoxConstructor({
            propsData: {
              message,
              type: "error",
              top: (this.instanceList.length + 1) * 55,
            },
          });
          let $Message = messageBox.$mount();
          this.vmError = $Message;
          this.instanceList.push({ ...$Message, types: "vmError" });
          document.body.appendChild($Message.$el);
          setTimeout(() => {
            this.hide("vmError");
          }, 6000);
        }
      },
    };
  },
};

使用方法

<template>
  <div id="app">
    <button @click="handleShowMessageBox">显示</button>
    <button @click="handleHideMessageBox">隐藏</button>
  </div>
</template>
<script>
import MessageBox from "./components/MessageBox/index.vue";
export default {
  name: "App",
  components: { MessageBox },
  methods: {
    handleShowMessageBox() {
      this.$Message.success("恭喜你,这是一条成功消息");
      this.$Message.error("sorry,这是一条失败消息");
    },
    handleHideMessageBox() {
      this.$Message.hide();
    },
  },
};
</script>

效果图

总结

  • 要通过js的方式通过api调用生成,关键在在于Vue.extend函数的使用,上面只是个简单版本的,可以根据自己的需要,自动加以扩展。
  • 我们这种弹窗组件一般做成单例,因此点击的时候不会重复出现相同类型的组件。

以上就是Vue.extend实现组件库message组件示例详解的详细内容,更多关于Vue.extend message组件库的资料请关注阿兔在线工具其它相关文章!

点赞(0)

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部