在vue开发中最方便的就是组件,把一些共用的地方都抽取成一个组件,需要用到的地方引入就可以。但是像一些alert,toast等模态框,每次引入就会很麻烦,能不能像elementui那样呢?使用Vue.use()注册后,通过调用this.$alert就可以使用。这样就需要vue插件来实现了。第二篇:传送门
一、开发插件前的准备
想要开发一个插件发布到npm上,就先要去npm官网查询自己插件名字有没有重复,如果没有重复,那就可用,本例中我们插件名称为vue-modal-plugins,很庆幸在npm上没有被人使用。
1、在本地创建目录,然后npm init
init结束后会在目录生成一个package.json文件
{
"name": "vue-modal-plugins",
"version": "1.0.0",
"description": "a modal in vue",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"vue-modal",
"vue-toast",
"vue-modal-plugins"
],
"author": "mzong",
"license": "ISC"
}
复制代码
2、在根目录创建一个src文件夹来存放源码
在src目录下创建一个lib文件夹,存放插件相关源码,此时目录结构如下:
其中index.js是封装插件的主要js,稍后讲解。vue-modal-plugins.vue文件就是平时的vue组件。二、插件的具体实现
接下来具体看lib两个文件中的代码
1、vue-modal-plugins.vue文件
这个文件很简单,本例中我们只是用来显示一段文字,类似toast效果。
<template>
<transition name="fade">
<div class="vue-modal" v-show="visible">
<div class="vue-content">
{{ message }}
</div>
</div>
</transition>
</template>
<script type="text/ecmascript-6">
export default {
data () {
return {
message: 'hello world!',
visible: false
}
},
methods: {
}
}
</script>
<style scoped>
.vue-modal{
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.3);
z-index: 200;
}
.vue-content{
position: fixed;
top: 50%;
left: 50%;
padding: 10px;
width: 270px;
height: auto;
text-align: center;
transform: translate(-50%, -50%);
z-index: 201;
border-radius: 4px;
color: #fff;
background: rgba(0,0,0,.65);
}
.fade-enter-active{
animation: fade-in .3s;
}
.fade-leave-active{
animation: fade-out .3s;
}
@keyframes fade-in {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@keyframes fade-out {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
</style>
复制代码
2、index.js文件
该文件是插件的主要实现,比如自动导入组件并且$mount挂载到元素上等等。 先来看一下vue官网对插件的定义
接下来我们来看看一个插件的主要写法// 初始化vue插件对象
let Modal = {}
// vue插件必须有一个公开的install方法。
// 这个方法的第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象
Modal.install = function (Vue, options) {
// Vue会在Vue.use()时传递进来,options是选项对象。Vue.use(Modal, { someOption: true })
...
}
// 最后将插件导出,在main.js中可以使用Vue.use(Modal)就可以使用啦。
export default Modal
复制代码
我们在install方法里面写具体实现代码,本例用到来vue的第4种方法,添加vue实例方法来实现。
import vueModalPlugins from './vue-modal-plugins'
// 初始化vue插件对象
let Modal = {}
// vue插件必须有一个公开的install方法。
// 这个方法的第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象
Modal.install = function (Vue, options) {
// Vue会在Vue.use()时传递进来,options是全局options
// 默认选项
let opts = {
duration: 3000
}
for (let props in options) {
if (options.hasOwnProperty(props)) {
opts[props] = options[props]
}
}
// 添加实例方法,在项目中可以使用this.$modal()来调用
Vue.prototype.$modal = function (message, option) {
// 上面那个options是全局的,也可以通过局部option来替换全局的
if (typeof option == 'object') {
for (let props in option) {
if (option.hasOwnProperty(props)) {
opts[props] = option[props]
}
}
}
// 创建构造器,Vue.extend就是继承一个vue组件,vueModalController跟Vue({})返回的对象一样
const vueModalController = Vue.extend(vueModalPlugins)
// 创建完组件实例后,进行挂载到el上
// 也可以通过new vueModalController({el: document.createElement('div')})进行挂载。
// 这种写法跟let vueApp = new Vue({...})完全一样
let instance = new vueModalController().$mount(document.createElement('div'))
// 通过instance实例可以修改data里面的数据,message就是从外部调用传进来的
instance.message = message
// 创建完实例之后,要把el添加到body中
document.body.appendChild(instance.$el)
Vue.nextTick(function() {
// 默认调用设置显示为show
instance.visible = true
})
// 在几s后让弹框隐藏
setTimeout(function() {
instance.visible = false
document.body.removeChild(instance.$el)
}, opts.duration)
}
// 如果$modal有多个方法,就给$modal添加子方法。
// 这样可以调用this.$modal.show()
Vue.prototype.$modal['show'] = function (message, option) {
Vue.prototype.$modal(message, option)
}
}
// 最后将插件到处,在main.js中可以使用Vue.use(Modal)就可以使用啦。
export default Modal
复制代码
具体思路
- 把组件引进来,通过Vue.extend创建组件构造器
- 通过new一个构造器创建instance实例,用来操作.vue文件的数据
- 把instance实例进行挂载,挂载完就appendChild到body中。
- 用完对instance进行removeChild。
三、插件使用
我们平时在npm install包的时候,会自动放在node_modules目录里,本次我们在本地使用,就先将整个插件文件夹放到node_modules里面,其中有一点需要注意的,就是要把package.json中的main入口文件修改为
"main": "./src/lib/index.js"
复制代码
这样一个插件就完全准备好了,接下来我们在项目中使用
在main.js中引入并且注册
import vueModalPlugins from 'vue-modal-plugins'
Vue.use(vueModalPlugins)
复制代码
我们随便找一个页面调用,测试效果
created () {
this.$modal.show('哈哈哈')
}
复制代码
测试成功!!!
下一节我们就把插件放到npm上