Vue插件通常来为Vue添加全局功能。其实现原理是暴露一个install方法,方法中传入Vue构造函数以及一个可选的选项对象,通过Vue.use()方法即可引入组件。下面实现一个自定义全局弹窗组件
1.首先编写组件的基础模板和基础方法(显示与延时关闭组件,销毁组件)。
<template>
<div class="box" v-if="isNoticeShow">
<h3>{{title}}</h3>
<p class="box-content">{{message}}</p>
</div>
</template>
<script>
export default {
props: {
title: {
type: String,
default: ''
},
message: {
type: String,
default: ''
},
duration: {
type: Number,
default: 1000
}
},
data () {
return {
isNoticeShow: false
}
},
methods: {
show () {
this.isNoticeShow = true
setTimeout(this.hide, this.duration)
},
hide () {
this.isNoticeShow = false
// 清除自己
this.remove()
}
}
}
</script>
2.创建组件实例
接下来需要创建组件实例,传入组件模板和参数,并返回组件实例。
具体实现步骤如下
- 获取构造函数,这里使用render函数,因此要引入vue。
- 将创建完成的dom追加到页面根节点中。
- 添加自我销毁方法。
- 挂载到vue原型并导出,下面是具体代码实现
import Vue from 'vue'
import Notice from '../views/slots/Notice'
function create (Component, props) {
const vm = new Vue({
/* render函数用来生成虚拟dom,接收一个createElement函数(一般称之h函数),
并返回该函数的执行结果(生成的虚拟dom)。
h函数接受三个参数,
1.一个标签名或组件选项对象。
2.与模板中属性对应的数据对象。
3.子节点。
生成的虚拟dom需要经过挂载($mount)才能变成真实dom
*/
render: h => h(Component, { props })
// 这里不指定宿主元素,因为直接指定body的话会将已有的内容替换掉。
}).$mount()
/* 通过dom操作追加元素 $el可以获取真实dom */
document.body.appendChild(vm.$el)
/* 获取组件实例 */
const comp = vm.$children[0]
/* 添加销毁组件的方法 */
comp.remove = function () {
document.body.removeChild(vm.$el)
vm.$destroy()
}
return comp
}
export default {
/* install方法实现的需求是 在使用组件时不需要再传入组件模板,只需传入参数,
因此使用柯里化函数实现。*/
install(Vue) {
Vue.prototype.$notice = function(options) {
return create(Notice, options)
}
}
}
3.注册组件
在main.js中使用use方法注册
import create from './utils/create'
Vue.use(create)
4.使用组件
const notice = this.$notice({
title: '自定义弹窗',
message: '登陆成功',
duration: 1000
})
notice.show()
最终效果如下
最终实现效果.png
网友评论