vue 自定义注册全局notification消息通知组件

效果图
notice目录结构
project
Notice.vue

<template>
  <transition name="notice-fade">
    <div v-if="visible" :class="wrapClasses">
      <span class="content">
        <i v-if="type === 'success'" class="el-icon-success"></i>
        <i v-if="type === 'warning'" class="el-icon-warning"></i>
        <i v-if="type === 'error'" class="el-icon-error"></i>
        <i v-if="type === 'info'" class="el-icon-info"></i>
        <span :class="[prefixCls+'-content']">
          {{msg}}
        </span>
      </span>
    </div>
  </transition>
</template>

<script>
const prefixCls = 'notice'
export default {
  name: 'Notice',
  data () {
    return {
      visible: false,
      type: 'info',
      msg: '',
      duration: 1500,
      prefixCls: prefixCls
    }
  },
  computed: {
    wrapClasses () {
      return [`${prefixCls}`, `${prefixCls}-${this.type}`]
    }
  },
  mounted () {
    this.setTimer()
  },
  methods: {
    setTimer () {
      setTimeout(() => {
        this.close() // 3000ms之后调用关闭方法
      }, this.duration)
    },
    close () {
      this.visible = false
      setTimeout(() => {
        this.$destroy()
        this.$el.parentNode.removeChild(this.$el) // 从DOM里将这个组件移除
      }, 500)
    }
  }
}
</script>

<style lang="less" scoped>
  .notice-fade-enter-active,
  .notice-fade-leave-active {
    transition: all 0.3s ease;
  }
  .notice-fade-enter, .notice-fade-leave-to {
    transform: translateY(-20px);
    opacity: 0;
  }
  .notice {
    background-color: transparent!important;
    margin-bottom: 15px;
    .content{
      background-color: #fff;
      border-radius: 5px;
      box-shadow: 0 0 10px rgba(34, 34, 34, 0.2);
      padding: 5px 8px;
      display: inline-block;
      width: auto;
      i{
        margin-right: 3px;
      }
    }
  }
  .notice-success {
    background-color: #fff;
    color: #67C23A;
  }
  .notice-info {
    color: #909399;
    background-color: #fff;
  }
  .notice-warning {
    color: #E6A23C;
    background-color: #fff;
  }
  .notice-error {
    background-color: #fff;
    color: #F56C6C;
  }
  .notice-content {
    font-size: 14px;
  }
</style>

index.js

import Vue from 'vue'
import NoticeTpl from './Notice.vue'
const NoticeConstructor = Vue.extend(NoticeTpl)

let nId = 1
//在body下新建的标签类名
let tagClass = 'dialog-notice'

const Message = options => {
  if (JSON.stringify(options) === undefined) { return false }
  let id = 'notice-' + nId++
  options = options || {}
  if (typeof options === 'string') {
    options = {
      msg: options
    }
  }
  const NoticeInstance = new NoticeConstructor({
    data: options
  })
  NoticeInstance.id = id
  NoticeInstance.vm = NoticeInstance.$mount()
  NoticeInstance.vm.visible = true
  NoticeInstance.dom = NoticeInstance.vm.$el
  if (!document.querySelector(`body > .${tagClass}`)) {
    let div = document.createElement('div')
    div.classList.add(tagClass)
    document.body.appendChild(div)
    document.querySelector(`body > .${tagClass}`).appendChild(NoticeInstance.dom)
  }
  document.querySelector(`body > .${tagClass}`).appendChild(NoticeInstance.dom)
  // NoticeInstance.dom.style.zIndex = nId + 1001
  return NoticeInstance.vm
}
['success', 'warning', 'info', 'error'].forEach(type => {
  Message[type] = options => {
    if (typeof options === 'string') {
      options = {
        message: options
      }
    }
    options.type = type
    return Message(options)
  }
})

export default {
  install (Vue, options = {}) {
    Vue.prototype.$notice = Message
  }
}

全局css文件

.dialog-notice{
    position: fixed;
    top: 85px;
    display: inline-block;
    max-width: 300px;
    left: 0;
    right: 0;
    margin: 0 auto 10px auto;
    background-color: transparent!important;
    text-align: center;
    z-index: 9999;
}

main.js中注册使用

import Notice from './common/notice/index.js'

Vue.use(Notice)

使用

this.prototype.$notice.success({
  msg: '代码复制成功'
})
发布了25 篇原创文章 · 获赞 4 · 访问量 123万+

猜你喜欢

转载自blog.csdn.net/weixin_45266125/article/details/103458972