当前位置: 移动技术网 > IT编程>脚本编程>vue.js > VUE2实现事件驱动弹窗示例

VUE2实现事件驱动弹窗示例

2017年12月12日  | 移动技术网IT编程  | 我要评论

max232,宠魅笔趣阁,1.85传奇似发服网

前几天想了解vue如何写弹窗组件

有以下两种可取的写法:

1.状态管理 如果弹窗组件放在根组件,使用vuex来管理组件的show和hide。放在组件内,通过增加v-show或v-if来控制,可结合slot,定义不同需求的弹窗

2.事件管理 注册一个全局事件来打开弹窗,传入需展示的文字和相关的逻辑控制,可结合promise,实现异步

觉得对用像confirme和propmt这类弹窗,还是事件驱动的好。最好就是能使用promise回调。

于是手痒就写了一个。下面是代码。

propmt.js

import vue from 'vue'
import promptcomponent from './prompt.vue' // 引入弹窗的vue文件
const promptconstructor = vue.extend(promptcomponent); // 注册组件
let instance = new promptconstructor().$mount(''); // 获得组件的实例

document.body.appendchild(instance.$el); // 将组件的element插入到body中
const alert = (text,oktext)=>{
  if(instance.show === true) { //防止多次触发
    return;
  }
  // 为弹窗数据赋值
  instance.show = true; 
  instance.isalert = true;
  instance.oktext = oktext||'确定';
  instance.message = text;
  //返回一个promise对象,并为按钮添加事件监听
  return new promise(function(resolve,reject) {
    instance.$refs.okbtn.addeventlistener('click',function() {
      instance.show = false;
      resolve(true);
    })
  })
};
const confirm = (text,oktext,canceltext)=>{
  if(instance.show === true) {
    return;
  }
  instance.show = true;
  instance.oktext = oktext||'确定';
  instance.canceltext = canceltext||'取消';
  instance.message = text;
  return new promise(function(resolve,reject) {
    instance.$refs.cancelbtn.addeventlistener('click',function() {
      instance.show = false;
      resolve(false);
    });
    instance.$refs.okbtn.addeventlistener('click',function() {
      instance.show = false;
      resolve(true);
    })
  })
};
const prompt = (text,oktext,inputtype, defaultvalue)=>{
  if(instance.show === true) {
    return;
  }
  instance.show = true;
  instance.isprompt = true;
  instance.oktext = oktext||'确定';
  instance.message = text;
  instance.inputtype = inputtype || 'text';
  instance.inputvalue = defaultvalue || '';
  return new promise(function(resolve,reject) {
    instance.$refs.okbtn.addeventlistener('click',function() {
      instance.show = false;
      resolve(instance.inputvalue);
    })
  })
};

export {alert,confirm,prompt}

prompt.vue

<style lang="less" scoped>
  .confirm-enter-active {
    transition: all .2s;
  }

  .confirm-leave-active {
    transition: opacity .2s;
  }

  .confirm-leave-to {
    opacity: 0;
  }

  .confirm-enter {
    opacity: 0;
  }

  .confirm {
    position: relative;
    font-family: pingfangsc-regular;
    font-size: 17px;
    -webkit-user-select: none;
    user-select: none;
    // 遮罩层样式
    .masker {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background-color: rgba(0, 0, 0, .4);
      -webkit-transition: opacity .1s linear;
      transition: opacity .1s linear;
      z-index: 100;
    }
    // 入库数据错误样式
    .box {
      position: absolute;
      top: 50%;
      left: 50%;
      width: 72%;
      -webkit-transform: translate(-50%, -50%);
      transform: translate(-50%, -50%);
      text-align: center;
      border-radius: 12px;
      background-color: #fff;
      .message {
        height: 97px;
        line-height: 24px;
        font-family: pingfangsc-regular;
        font-size: 17px;
        vertical-align: middle;
        color: #999;
        letter-spacing: -0.41px;
        p {
          margin: 20px auto 0 auto;
          vertical-align: middle;
        }
        &::after {
          content: '';
          height: 100%;
        }
      }
      .prompt {
        margin: 20px 0;
        width: 100%;
        p {
          margin: 5px auto;
          font-size: 17px;
          line-height: 24px;
        }
        input {
          margin: 5px auto;
          border: 1px solid #333;
          border-radius: 6px;
          width: 100px;
          height: 30px;
          font-size: 14px;
          line-height: 20px;
          text-align: center;
        }
      }
      .button-group {
        a {
          width: calc(50% - 0.5px);
          text-align: center;
          font-size: 17px;
          line-height: 43px;
          color: blue;
        }
        .max-width {
          width: 100% !important;;
        }
      }
    }
  }
</style>
<template>
  <transition name="confirm">
    <div class="confirm" v-show="show">
      <div class="masker" @touchmove.prevent>
        <div class="box">
          <div class="message" v-if="!isprompt">
            <p>{{message}}</p>
          </div>
          <div class="prompt" v-if="isprompt">
            <p>{{message}}</p>
            <input type="text" v-model="inputvalue" v-if="inputtype === 'text'" ref="inputel">
            <input type="tel" v-model.number="inputvalue" @keydown="entercheck" v-if="inputtype === 'tel'" ref="inputel">
          </div>
          <div class="button-group clearfix bd-top">
            <a class="bd-right fl" ref="cancelbtn" v-show="!isalert && !isprompt">{{canceltext}}</a>
            <a class="fr" ref="okbtn" :class="{'max-width': isalert || isprompt}">{{oktext}}</a>
          </div>
        </div>
      </div>
    </div>
  </transition>
</template>
<script type="text/ecmascript-6">
  import {mapstate} from 'vuex'
  export default{
    data() {
      return {
        show: false,
        message: '请输入提示语',
        oktext: '确定',
        canceltext: '取消',
        isalert: false,
        isprompt: false,
        inputvalue: '',
        inputtype: ''
      }
    },
    methods: {
      // 金额输入框校验
      entercheck(event) {
        // 只允许输入数字,删除键,11位数字
        if (event.keycode === 46 || event.keycode === 8) {
          return;
        }
        if (event.keycode < 47 || event.keycode > 58 || event.keycode === 190) {
          event.returnvalue = false;
        }
      },
    },
    watch: {
      show(){
        if (this.show) {
          this.$nexttick(() => {
            console.log(this.$refs.inputel);
            console.log(this.inputtype);
            this.$refs.inputel.focus();
          });
        }
      }
    }
  }
</script>

main.js

import {alert,prompt,confirm} from '../lib/components/prompt/prompt.js'

vue.prototype.alert = function(text,oktext) {
  return alert(text,oktext)
};
vue.prototype.confirm = function(text,oktext,canceltext) {
  return confirm(text,oktext,canceltext)
};
vue.prototype.prompt = function(text,oktext,inputtype, defaultvalue) {
  return prompt(text,oktext,inputtype, defaultvalue)
};
component.vue:

inputname() {
  this.prompt('请输入名称','确认','text').then(res =>{
    // do something use res
  });
},

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网