随着简单易用的vue流行开来,国人也贡献了很多vue生态圈的框架、插件。目前根据需求需要写一个移动端的支付功能的页面,因为比较简单,故不使用任何UI框架,相应的提示、loading自己来写。
既然想要在组件内部直接使用this.fs这种方式来调用,那么就需要用到vue的install方法了。接下来亮代码:
首先定义toast文件夹,下面分别是toast.vue 以及index.js。
toast.vue:
html(搭配渐显效果):
<transition :name="fadeIn">
<div class="alertBox" v-show="show">
<div class="box" ref="boxid" id="box" :class="position" v-show="show">
{{text}}
</div>
</div>
</transition>
css(浮层样式编写,注意z-index的取值):
.box{
position: fixed;
top: 50%;
left: 50%;
width: auto;
height: auto;
background: rgba(0,0,0,.5);
text-align: center;
padding: 10px;
border-radius: 20px;
color: #fff;
font-size: .8rem;
z-index: 2000;
color: #fff;
}
.box.top{
top: 50px;
margin-top: 0;
}
.box.center{
top: 50%;
margin-top: -100px;
}
.box.bottom{
top: auto;
bottom: 50px;
margin-top: 0;
}
.fadeIn-enter-active, .fadeIn-leave-active{
transition: opacity .3s;
}
.fadeIn-enter, .fadeIn-leave-active{
opacity: 0;
}
.translate-top-enter-active, .translate-top-leave-active{
transition: all 0.3s cubic-bezier(.36,.66,.04,1);
}
.translate-top-enter, .translate-top-leave-active{
transform: translateY(-50%);
opacity: 0;
}
.translate-middle-enter-active, .translate-middle-leave-active{
transition: all 0.3s cubic-bezier(.36,.66,.04,1);
}
.translate-middle-enter, .translate-middle-leave-active{
transform: translateY(80%);
opacity: 0;
}
.translate-bottom-enter-active, .translate-bottom-leave-active{
transition: all 0.3s cubic-bezier(.36,.66,.04,1);
}
.translate-bottom-enter, .translate-bottom-leave-active{
transform: translateY(100%);
opacity: 0;
}
js(toast配置项):
props: {
show: { // 是否显示此toast
default: false
},
text: { // 提醒文字
default: 'loading'
},
position: { // 提醒容器位置,默认剧中
default: 'center'
},
time: { // 显示时间
default: 2000
},
transition: { // 是否开启动画
default: true
}
},
//监听显示状态
watch:{
show:function(){
//状态为true时 几秒后隐藏状态,网络上也有他人贡献,但是有bug,因此我改成这种监听的方式,可以无限放心地点
if(this.show){
//让toast实时计算高宽剧中
setTimeout(()=>{
this.$refs.boxid.style.marginLeft=-(this.$refs.boxid.clientWidth/2)+"px";
this.$refs.boxid.style.marginTop=-(this.$refs.boxid.clientHeight/2)+"px";
},10)
setTimeout(() => {
this.show = false
}, this.time)
}
}
},
computed: {
translate() { // 根据props,生成相对应的动画
if (!this.transition){
return ''
} else {
if (this.position === 'top') {
return 'translate-top'
} else if (this.position === 'middle') {
return 'translate-middle'
} else if (this.position === 'bottom') {
return 'translate-bottom'
}
}
},
fadeIn() { // show时来个渐显的效果
if (!this.transition) {
return ''
} else {
return 'fadeIn'
}
}
}
index.js(注册插件功能):
var ToastVue = require('./toast.vue') // 引入vue模板
var Toast = {} // 定义插件对象
Toast.install = function (Vue, options) { // vue的install方法,用于定义vue插件
// 如果toast还在,则不再执行
if(document.getElementsByClassName('alertBox').length){//class名字记得对上
return
}
let toastTpl = Vue.extend(ToastVue) // 创建vue构造器
let $vm = new toastTpl() // 实例化vue实例
// 此处使用$mount来手动开启编译。用$el来访问元素,并插入到body中
// el:提供一个在页面上已存在的DOM元素作为Vue实例的挂载目标。可以是css选择器,也可以是HTMLElement实例。
let tpl = $vm.$mount().$el
document.body.appendChild(tpl)
Vue.prototype.$toast = { // 在Vue的原型上添加实例方法,以全局调用
//此处最好使用这种方式,可开可关。
show(options) { // 控制toast显示的方法
if (typeof options === 'string') { // 对参数进行判断
$vm.text = options // 传入props
}
else if (typeof options === 'object') {
Object.assign($vm, options) // 合并参数与实例
}
$vm.show = true // 显示toast
},
hide() { // 控制toast隐藏的方法
$vm.show = false
}
}
}
export default Toast;
此后在main.js入口文件调用就行:
import Toast from '@/components/Toast'
Vue.use(Toast)
loading的公共组件也是如此设计。
如果某一天能有比较漂亮的基础组件,那么会发布到git和npm上,让我们一起来慢慢开发属于自己公司的基础组件。。。
与君共勉!!!