Vue插件与组件
组件 (Component) 是用来构成你的 App 的业务模块,它的目标是 App.vue。
插件 (Plugin) 是用来加强你的技术栈的功能模块,它的目标是 Vue 自己。
此篇文章主要是写一个编写插件的过程,具体功能还待完善。html
就Loading为例:若是是组件,你须要在父组件里引入,注册 · · · ·
若是你封装成一个全局的插件,你就能够直接this.loading.show()
。随时显示它。vue
Vue.js 的插件应该暴露一个 install 方法。这个方法的第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象。web
涉及知识点:npm
Vue.extend
elapi
loading
└───index.js
└───loading.vue
复制代码
index.js
暴露一个 install 方法,loading.vue
loading的UI界面bash
<!-- loading.vue -->
<template>
<div class="custom-loading" v-if="show">
<div class="custom-loading-Mask"></div>
<div class="custom-loading-box">
<div class="custom-loading-content">
<img :src="icon" />
<span>{{text}}</span>
<em :style="{borderLeftColor:progressColor}"></em>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return{
icon:require('../assets/img/wx.png'),
show:false,
text:'加载中...',
progressColor:'#ff0000',
}
},
}
</script>
<style>
.custom-loading{
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: 9999999999;
display: flex;
justify-content: center;
align-items: center;
}
.custom-loading-Mask {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background: rgba(0,0,0,.4);
}
.custom-loading-box{
width: 138px;
height: 138px;
border-radius: 6px;
background: #fff;
position: relative;
z-index: 100;
display: flex;
justify-content: center;
align-items: center;
}
.custom-loading-content{
width: 106px;
height: 106px;
border-radius: 50%;
display: flex;
justify-content: center;
align-content:center;
flex-wrap: wrap;
border: 3px solid #eee;
position: relative;
}
.custom-loading-content:after{
}
@-webkit-keyframes motion{
0%{-webkit-transform:rotate(0deg);}
25%{-webkit-transform:rotate(90deg);}
50%{-webkit-transform:rotate(180deg);}
75%{-webkit-transform:rotate(270deg);}
100%{-webkit-transform:rotate(360deg);}
}
.custom-loading-content img{
width: 30px;
height: 30px;
margin-bottom: 20px;
}
.custom-loading-content span{
width: 100%;
text-align: center;
font-size: 12px;
}
.custom-loading-content em{
position: absolute;
width: 106px;
height: 106px;
top: -3px;
left: -3px;
border: 3px solid transparent;
border-left: 3px solid;
border-radius: 50%;
box-sizing: content-box;
-webkit-animation: motion 1s infinite linear;
animation: motion 1s infinite linear;
}
</style>
复制代码
//index.js
import myLoading from './loading.vue';
export default {
/*
* Vue:Vue 构造器
* options:可选插件参数
*/
install(Vue, options) {
/*
*Vue.extend: https://cn.vuejs.org/v2/api/#Vue-extend
*使用基础 Vue.extend 构造器,建立一个“子类” (Loading)。参数是一个包含组件选项的对象(myLoading)。
*而后 建立一个 Loading 的实例 Profile 挂载到一个HTMLElement实例上
*/
const Loading = Vue.extend(myLoading);
const Profile = new Loading({
el: document.createElement('div')
});
/*
*el: https://cn.vuejs.org/v2/api/#el
*loading.vue中的template模板内容将会替换挂载的元素。挂载元素的内容都将被忽略。 *因此Profile.$el最终是template里面的内容
*/
//插入到 document.body
document.body.appendChild(Profile.$el);
//这里插件接收三个值 icon progressColor 若是注册的时候传入这些值则赋值给组件内默认值。
if(options){
if(options.icon)
Profile.icon = options.icon;
if(options.progressColor)
Profile.progressColor = options.progressColor;
}
//定义显示隐藏的方法 open 会传入一个text 字符串。若是有则赋值给组件内默认值。
const myLoadingMethod = {
open(text) {
Profile.show = true;
if(text){
Profile.text = text;
}
},
hide() {
Profile.show = false;
}
};
//添加实例方法 把自定义方法挂载到Vue构造器的上,这样每一个实例均可以调用。
Vue.prototype.$myLoading = myLoadingMethod;
}
}
复制代码
在main.js
里并发
//这里的 icon 要换成你本地的
import myLoading from './loading'
Vue.use(myLoading,{
icon:require('./assets/img/ali.png'),
progressColor:'blue'
})
复制代码
在须要使用loading组件里app
this.$myLoading.open();
setTimeout(() =>{
this.$myLoading.hide();
},3000)
复制代码
Toast
,Alert
,并发布到npm留着本身使用。