在我们初学组件时,只知道调用组件的时候通过import调用组件,然后显示的通过标签去调用,通过数据驱动来决定组件的显示与否,但是在看了element-ui的源码后,我才知道可以通过注册Vue原型,全局调用组件。接下来通过代码介绍原理

同样,我们需要先写一个message.vue来规定message组件显示的内容

<template>
  <transition name="message-fade">
    <div v-if="visible" :class="wrapClasses">
        <img class="message_img" :src="typeImg"/>
        <span class="">
          {{message}}
        </span>
    </div>        
  </transition>
</template>

<script>
  const prefixCls = 'message'
  export default {
    name: 'message',
    data () {
      return {
        visible: false,
        type:'info',
        message: '',
        duration: 3000
      }
    },
    computed:{
      typeImg(){
        return require(`./assets/${this.type}.svg`);
      },
      wrapClasses(){
        return[
          `${prefixCls}`,
          `${prefixCls}-${this.type}`
        ]
      }
    },
    methods: {
      setTimer() {
        setTimeout(() => {
          this.close() // 3000ms之后调用关闭方法
        }, this.duration)
      },
      close() {
        this.visible = false
        setTimeout(() => {
          this.$destroy(true)
          this.$el.parentNode.removeChild(this.$el) // 从DOM里将这个组件移除
        }, 500)
      }
    },
    mounted() {
      this.setTimer() // 挂载的时候就开始计时,3000ms后消失
    }
  }
</script>

在组件中没有props接收参数,那么message如何给其传参,就需要一个message.js文件去管理message.vue组件

import Vue from 'vue'

const NoticeConstructor = Vue.extend(require('./message.vue').default) // 直接将Vue组件作为Vue.extend的参数,在这里注意,高版本的vue-loader要添加.default

let nId = 1

const Message = (options) => {
  let id = 'notice-' + nId++;
  options = options || {};
  if (typeof options === 'string') {//如果只传入字符串,将其设置为显示的信息
    options = {
      message: options//这里的message就是message.vue中data中的message
    };
  }

  const NoticeInstance = new NoticeConstructor({// 实例化一个带有content内容的Notice
    data:options//在这里将你传过来的参数匹配到message.vue组件的data
  }) 
  //console.log(NoticeInstance);
  NoticeInstance.id = id;
  NoticeInstance.vm = NoticeInstance.$mount(); // 挂载但是并未插入dom,是一个完整的Vue实例
  NoticeInstance.vm.visible = true   //这里修改message.vue数据中的visible,这样message组件就显示出来
  //console.log(NoticeInstance.vm);
  NoticeInstance.dom = NoticeInstance.vm.$el    //获取到本实例的dom元素
  document.body.appendChild(NoticeInstance.dom) // 将dom插入body
  NoticeInstance.dom.style.zIndex = nId + 1001 // 后插入的Notice组件z-index加一,保证能盖在之前的上面
  return NoticeInstance.vm
};
['success', 'warning', 'info', 'error'].forEach(type => {//同element-ui一样,在给Message绑定四个方法,直接调用
    Message[type] = options => {
      if (typeof options === 'string') {
        options = {
          message: options
        };
      }
      options.type = type;
      return Message(options);
    };
  });

export default  Message;

在最后在入口文件main.js中调用message.js并添加Vue实例方法

import Message from './components/UI/message/message.js'

Vue.prototype.$message = Message;

之后直接通过this.$message({

 type:'success',

message:'11111111'

})或使用便捷方法this.$message.success('11111')调用

对于动画效果和css样式,我简单的写了一下,这里由于篇幅的原因,就不在描述,有需要的直接请到github上查看:

https://github.com/yanggreater/vue-personal-components/tree/master/message

 

最后感谢element-ui的开源和 博主https://blog.csdn.net/w178191520/article/details/79057784的启发

Logo

前往低代码交流专区

更多推荐