Vue.extend开发全局组件,可通过js直接调用方法来显示和关闭

Vue.extend开发全局组件,可通过js直接调用方法来显示和关闭

  Vue.extend是一个全局Api,平时我们在开发业务的时候很少会用到它,但有时候我们希望可以开发一些全局组件比如Loading,Notify,Message等组件时,这时候就可以使用Vue.extend,extend创建的是一个组件构造器,而不是一个具体的组件实例

     本文以开发个全局的loading加载组件为例,实现全局的遮罩层,并且实现通过js直接调用方法来控制组件显示和关闭,而不是通过components关键字来塞到每个vue文件里使用。

一、开发全局需要展示的组件,实现基本功能

<template>
  <transition name="custom-loading-fade">
    <!--loading遮罩层-->
    <div v-show="visible" class="custom-loading-mask">
      <!--loading中间的图标-->
      <div class="custom-loading-spinner">
        <i class="custom-spinner-icon"></i>
        <!--loading上面显示的文字-->
        <p class="custom-loading-text">{{ text }}</p>
      </div>
    </div>
  </transition>
</template>
<script>
//这里如果是作为components插入到vue文件里一般需要设置为props传值,但是本方法是通过extend,用data定义这些变量即可,不需要用props实现父子传值
/*
export default {
  props: {
  // 是否显示loading
    visible: {
      type: Boolean,
      default: false
    },
    // loading上面的显示文字
    text: {
      type: String,
      default: ''
    }
  },  */   //上部分代码已经屏蔽
data() {
    return {
      text: '',
      visible: false
    }
  }
}
</script>

二、新建loading.js文件,利用vue.extend改造上面的组件

//新建一个loading.js文件

其主要思路是:

1、引入vue

import Vue from 'vue'

2、引入组件

import alert from '../components/commons/alert/index.vue'

3、扩展vue,生成构造函数

const alertBox = Vue.extend(alert)

4、声明函数 传入options

function alertBoxx (options){

5、new一个新对象

var alert = new alertBox({

6、创建el

el:document.createElement('div'),

7、添加数据

data(){

return{

Obj:{

isshow:true,

message:options.content,

btns:{

confirm:true,

cancel:true

}

}

}

},

8、添加方法

methods:{

confirm:options.callback

}

})

9、获取body 并将元素添加到body

document.querySelector('body').appendChild(alert.$el)

 

Vue.nextTick(()=>{

alert.Obj.isshow= true

})

}

10、挂载到vue 并暴露

function install(){

Vue.prototype.$alert= alertBoxx

}

export default install
import Vue from 'vue'
import LoadingComponent from './loading.vue'

// 通过Vue.extend将组件包装成一个子类,返回一个构造函数
const LoadingConstructor = Vue.extend(LoadingComponent)
//这上面三行都是固定的套路,引入文件,设置构造函数

let loading = undefined

LoadingConstructor.prototype.close = function() {
  // 如果loading 有引用,则去掉引用
  if (loading) {
    loading = undefined
  }
  // 先将组件隐藏
  this.visible = false
  // 延迟300毫秒,等待loading关闭动画执行完之后销毁组件
  setTimeout(() => {
    // 移除挂载的dom元素
    if (this.$el && this.$el.parentNode) {
      this.$el.parentNode.removeChild(this.$el)
    }
    // 调用组件的$destroy方法进行组件销毁
    this.$destroy()
  }, 300)
}



const Loading = (options = {}) => {
  // 如果组件已渲染,则返回即可
  if (loading) {
    return loading
  }
  // 要挂载的元素
  const parent = document.body
  // 组件属性
  const opts = {
    text: '',
    ...options
  }
  // 通过构造函数初始化组件 相当于 new Vue()
  const instance = new LoadingConstructor({
    el: document.createElement('div'),
    data: opts
  })
  // 将loading元素挂在到parent上面
  parent.appendChild(instance.$el)
  // 显示loading
  Vue.nextTick(() => {
    instance.visible = true
  })
  // 将组件实例赋值给loading
  loading = instance
  return instance
}
Vue.prototype.$loading = Loading    //这绑定的目的是为了在任何地方可以使用 this.$loading()
export default Loading

三、入口js文件中,全局注册

import customLoading from './loading.js'
Vue.use(customLoading )

四、使用

this.$loading()  //即可调用出Loading.vue的文件

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值