vue简单项目之toast、loading的公共组件

随着简单易用的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上,让我们一起来慢慢开发属于自己公司的基础组件。。。

与君共勉!!!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容