使用Vue.extend()编写vue插件

本文介绍了如何使用Vue.extend()创建一个自定义的Toast组件,并将其作为一个插件全局注册。详细步骤包括组件的编写、Vue.extend()的应用以及在main.js中安装和使用。最后展示了具体的使用示例,通过传递props和插槽内容实现弹窗功能。
摘要由CSDN通过智能技术生成

1.前言

今天,我们使用Vue.extend()编程式的写法来编写一个vue插件,本质是将插件实例挂载到Vue的原型上。然后,就像element-ui的toast组件那样,使用this.$toast()实例方法去调用插件。

2.Vue.extend()

使用Vue这个基础构造器,构造出一个“子类”,其实就是个构造函数,通过new运算符生成vue实例。具体见官方文档Vue-extend

3.如何编程式使用组件呢

比如,我们要实现个弹窗功能。通过编程式导航,我们就不用在模板中写了,可以使用js直接编写唤出弹窗。首先,我们正常的编写弹窗组件。如下:

<template>
  <div class="gulu-toast" :class="toastClasses">
    <div class="toast" ref="toast">
      <div class="message">
        <slot v-if="!enableHtml"></slot>
        <div v-else v-html="$slots.default[0]"></div>
      </div>
      <div class="line" ref="line"></div>
      <span class="close" v-if="closeButton" @click="onClickClose">
        {{closeButton.text}}
      </span>
    </div>
  </div>
</template>
<script>
  //构造组件的选项
  export default {
    name: 'Toast',
    props: {
      autoClose: {
        type: [Boolean, Number],
        default: 5,
        validator (value) {
          return value === false || typeof value === 'number';
        }
      },
      closeButton: {
        type: Object,
        default () {
          return {
            text: '关闭', callback: undefined
          }
        }
      },
      enableHtml: {
        type: Boolean,
        default: false
      },
      position: {
        type: String,
        default: 'top',
        validator (value) {
          return ['top', 'bottom', 'middle'].indexOf(value) >= 0
        }
      }
    },
    mounted () {
      // 这里是为了防止不断点击,出现多个弹窗
      const toast = document.getElementsByClassName('gulu-toast')[0]
      toast && document.body.removeChild(toast)
      this.updateStyles()
      this.execAutoClose()
    },
    computed: {
      toastClasses () {
        return {
          [`position-${this.position}`]: true
        }
      }
    },
    methods: {
      updateStyles () {
        this.$nextTick(() => {
          this.$refs.line.style.height =
            `${this.$refs.toast.getBoundingClientRect().height}px`
        })
      },
      execAutoClose () {
        if (this.autoClose) {
          setTimeout(() => {
            this.close()
          }, this.autoClose * 1000)
        }
      },
      close () {
        this.$el.remove()
        this.$emit('close')
        this.$destroy()
      },
      onClickClose () {
        this.close()
        if (this.closeButton && typeof this.closeButton.callback === 'function') {
          this.closeButton.callback(this)//this === toast实例
        }
      }
    }
  }
</script>

接下来,就是Vue.extend()出场了。

import Toast from './src/toast.vue';

Toast.install = function (Vue) {
	// 其实就是全局挂载使用
    Vue.prototype.$toast = function (text, props) {
        const ToastMain = Vue.extend(Toast)
        const instance = new ToastMain({
            propsData: props // 这里必须是propsData
        })
        instance.$slots.default = [text] // 插槽内容
        // instance.$mount().$el 该段代码意义为:
        // 文档之外渲染,并且获取该实例的根DOM元素,将其插入到body元素中。
        document.body.appendChild(instance.$mount().$el) 
    }
}
export default Toast

我们在main.js入口文件中,使用Vue.use()安装后,就可以在任何地方使用了~~。

4.具体使用

this.$toast("关闭吗?", {
        closeButton: {
          text: "关闭",
          callback: () => {
            console.log('已经关闭了');
          },
        },
        autoClose: 12,
        position: 'bottom'
      });

5.总结

  • 首先,Vue.extend 获得是一个构造函数,可以通过实例化生成一个 Vue 实例。
  • 实例化时可以向这个实例传入参数,但是需要注意的是 props 的值需要通过 propsData 属性来传递。
  • 还可以通过$slots来自定义插槽内容。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值