vue-自定义插件

688 阅读1分钟

this.$message的实现方式

element的$message使用起来很方便,而且和我们平常使用组件的方式很不同,所有很好奇其实现方式。在查询文档和网上其他资料的后,大概明白了原理。在此分享一下。

样式准备

第一步在components创建一个目录,然后创建一个notice.vue和notice.js连个文件(文件名自定义)。

vue文件,组件文件内容根据自己需求自定义

<template>

  <transition name="fade">
    <div class="cus-message" v-show="isShow" @click="hide">
      <div class="cus-message-content">
        <div class="cus-message-title">{{title}}</div>
        <div class="cus-message-text">{{message}}</div>
      </div>
    </div>
  </transition>
  <!-- </div> -->
</template>

<script>
export default {
  name: "notice-component",
  props: {
    title: {
      type: String,
      default: ''
    },
    message: {
      type: String,
      default: ''
    },
    duration: {
      type: Number,
      default: 1000
    },
    onClose: {
      type: Function,
      default: () => { }
    }
  },
  data () {
    return {
      isShow: false,
    }
  },
  methods: {
    show () {
      this.isShow = true
      setTimeout(this.hide, this.duration)
    },
    hide () {
      this.isShow = false
      this.remove()
      this.onClose && this.onClose()
    },
  },
}
</script>

<style  scoped>
.cus-message {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  /* bottom: 0; */
  margin: auto;
  z-index: 9999;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
}
.fade-enter-active {
  transition: all 0.3s;
}
.fade-leave-active {
  transition: all 0.3s;
}
.fade-enter,
.fade-leave-to {
  opacity: 0;
}
</style>

js文件中进行插件编写

// 导入所需组件
import noteComp from './notice.vue'
const cusNotice = {
  install (Vue) {// 一定要install的实现,详情请查看vue插槽编写文档
    const noticeBox = (options = {}) => {
           // 盛放内容
    }
     Vue.prototype.$notice = noticeBox
  }
}
export default cusNotice

方式1

  const Ctr = Vue.extend(noteComp) 
  const comp = new Ctr({ propsData: options }).$mount() //extend +$mount获得组件 ,使用propsData为组件传入参数,效果和平时组件props类似
    document.body.appendChild(comp.$el)// 将组件append入body中
    comp.show() // 调用组件内方法,显示组件
    comp.remove = () => { // 添加romve方法,在组件消失后,删除组件的对应的DOM节点
      document.body.removeChild(comp.$el)
      comp.$destroy()//销毁组件实例
    }
    return comp

完整代码

import noteComp from './notice.vue'
const cusNotice = {
  install (Vue) {
    const noticeBox = (options = {}) => {
      const Ctr = Vue.extend(noteComp)
      const comp = new Ctr({ propsData: options }).$mount()
      document.body.appendChild(comp.$el)
      comp.show()
      comp.remove = () => {
        console.log('remove')
        document.body.removeChild(comp.$el)
        comp.$destroy()
      }
      return comp
    }
    Vue.prototype.$notice = noticeBox
  }
}

export default cusNotice

使用方式在main.js中导入

import cusNotice from '@/components/notice/notice.js'
Vue.use(cusNotice)

根据需求在对应地方使用

this.$notice({
    title: '提示',
    message: '提示信息',
    type: 'success',
    duration: 2000,
    onClose: () => {
      console.log('关闭')
    }
  })

效果展示 企业微信截图_16547629413867.png

方式2

借用Vue实现

      const vm = new Vue({
        render: h => h(noteComp, { props: options })
      }).$mount() // 得到是一个Vue实例,和我们挂载在#app上的实例类似
      document.body.appendChild(vm.$el)
      const comp = vm.$children[0] //获取实例的第一个子组件
      document.body.appendChild(comp.$el)
      comp.show()
      comp.remove = () => {
        document.body.removeChild(comp.$el)
        comp.$destroy()
      }
      return comp

完整代码


import noteComp from './notice.vue'
const cusNotice = {
  install (Vue) {
    const noticeBox = (options = {}) => {
      const vm = new Vue({
        render: h => h(noteComp, { props: options })
      }).$mount() // 得到是一个Vue实例,和我们挂载在#app上的实例类似
      document.body.appendChild(vm.$el)
      const comp = vm.$children[0] //获取实例的第一个子组件
      document.body.appendChild(comp.$el)
      comp.show()
      comp.remove = () => {
        console.log('remove')
        document.body.removeChild(comp.$el)
        comp.$destroy()
      }
      return comp
    }
    Vue.prototype.$notice = noticeBox
  }
}

export default cusNotice

当然很多ui框架里面的功能更加强大,如果对其原理了解话,使用时也就不会觉得很神秘。