vue 封装插件

封装自定义验证插件 

实现效果

vue 封装插件

新建index.js

代码如下:

import Vue from 'vue'

let ClicaptchaConstructor = Vue.extend(require('./Clicaptcha.vue').default)

let instance;

const Clicaptcha = (options) => {
    options = options || {}
    instance = new ClicaptchaConstructor({
        data: options
    })
    instance.vm = instance.$mount()
    instance.dom = instance.vm.$el
    document.body.appendChild(instance.dom)
    return instance.vm
}

export default Clicaptcha;

 

插件核心代码:

新建vue 文件

Clicaptcha.vue

<template>
    <div>
        <div id="clicaptcha-box">
            <img class="clicaptcha-img" :src="imgSrc" ref="imgs" @load="setTitle" @click.prevent="record($event)" alt="验证码加载失败,请点击刷新按钮">
            <div class="clicaptcha-title" v-if="tip">
                {{tip}}
            </div>
            <div class="clicaptcha-title" v-else>
                请依次点击
                <span v-for="(text, index) in text" :key="index" :class="xy.length > index ? 'clicaptcha-clicked' : ''">{{text}}</span>
            </div>
            <div class="clicaptcha-refresh-box">
                <div class="clicaptcha-refresh-line clicaptcha-refresh-line-l"></div>
                <a href="javascript:;" class="clicaptcha-refresh-btn" title="刷新" @click="reset"></a>
                <div class="clicaptcha-refresh-line clicaptcha-refresh-line-r"></div>
            </div>
        </div>
        <div id="clicaptcha-mask" @click="close"></div>
    </div>
</template>

<script>
import qs from "qs";


export default {
    data() {
        return {
            src: "",
            imgSrc: "",
            mobile:"",
            success: "验证成功!",
            error: "未点中正确区域,请重试!",
            tip: "",
            isCheck: false,
            xy: [],
            text: [],
            token:'',
            callback: function() {},
            resetHandler:function (){}
        };
    },
    created() {
        this.loadImg();
    },
    methods: {
        loadImg() {
            this.imgSrc = this.src;
        },
        setTitle() {
            this.tip = "";
            //this.text = window.$cookies.get("clicaptcha_text").split(",");
            this.xy = [];
        },
        record(event) {
            var that = this;
            this.xy.push(event.detail.x-this.$refs.imgs.x + "," + (event.detail.y-this.$refs.imgs.y));
            if (this.xy.length == this.text.length) {
                let captchainfo = [
                    this.xy.join("-"),
                    this.$refs.imgs.width,
                    this.$refs.imgs.height
                ].join(";");
                this.$util.request('user/clicaptchaCheckCode',{
                    mobile:this.mobile,
                        do: "check",
                        info: captchainfo,
                        type:'3',
                        token:that.token
                    })
                .then(res=>{
                    this.callback(res)
                }).catch(error=>{console.log(error)});
            }
        },
        reset() {
            this.resetHandler();
        },
        close() {
            this.$destroy(true);
            console.log(this.$el)
            if(this.$el.parentNode){
            this.$el.parentNode.removeChild(this.$el);
            }
        }
    }
};
</script>

<style lang="scss" scoped>
#clicaptcha-box {
    width: 350px;
    height: 290px;
    padding: 15px;
    border: 1px solid #b1b3b8;
    background-color: #f5f6f7;
    position: fixed;
    z-index: 10000;
    left: 50%;
    top: 50%;
    margin-left: -191px;
    margin-top: -161px;
    border-radius: 10px;
    box-shadow: 0 0 0 1px hsla(0, 0%, 100%, 0.3) inset,
        0 0.5em 1em rgba(0, 0, 0, 0.6);
    .clicaptcha-img {
        width: 350px;
        height: 200px;
        border: none;
    }
    .clicaptcha-title {
        font-family: "Microsoft YaHei";
        height: 40px;
        line-height: 40px;
        font-size: 14px;
        text-align: center;
        color: #333;
        span {
            margin-left: 10px;
            font-size: 18px;
            font-weight: bold;
            color: #c00;
            &.clicaptcha-clicked {
                color: #069;
            }
        }
    }
    .clicaptcha-refresh-box {
        position: relative;
        margin-top: 10px;
    }
    .clicaptcha-refresh-line {
        position: absolute;
        top: 16px;
        width: 140px;
        height: 1px;
        background-color: #ccc;
    }
    .clicaptcha-refresh-line-l {
        left: 5px;
    }
    .clicaptcha-refresh-line-r {
        right: 5px;
    }
    .clicaptcha-refresh-btn {
        display: block;
        margin: 0 auto;
        width: 32px;
        height: 32px;
        background: url(../../static/refresh.png) no-repeat;
        &:hover {
            background-position: -32px 0;
        }
    }
}
#clicaptcha-mask {
    position: fixed;
    z-index: 9999;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    opacity: 0.5;
    background-color: rgb(0, 0, 0);
}
</style>

在vue 文件中引用

 

    import Clicaptcha from "@/components/clicaptcha/index.js";

调用方法:

            getcode(mobile){
                console.log(22)
                this.$util.request('user/clicaptchaCheckCode?type=3&do=1&info=1',{
                    param:'param',
                    mobile:mobile
                })
                .then(res=>{
                    let {data} =res.data;
                    this.cli = Clicaptcha({
                                    src: data.src,  
                                    success: "验证成功",
                                    token:data.token,
                                    mobile:mobile,
                                    text:data.clicaptcha_text.split(','),
                                    error: "未点中正确区域,请重试!", 
                                    withCredentials: true,
                                    callback:(res) => {
                                         console.log("文字验证码", res.data.code);
                                        if(res.data.code == 1){
                                            this.cli.close()
                                            uni.showToast({
                                                icon:"none",
                                                title:"验证码发送成功"
                                            })
                                            var str = '剩余'
                                            var i= 60;
                                            timer = setInterval(()=>{
                                                console.log(i);
                                                i--;
                                                this.btnTitle=str+i +'秒';
                                                if(i<=0){
                                                    this.disabled= false;
                                                    this.btnTitle='发送验证码';
                                                    clearInterval(timer);
                                                }
                                            },1000);
                                        }else{
                                            this.cli.close();
                                            this.disabled = false;
                                            setTimeout(()=>{
                                                clearInterval(timer);
                                            });
                                            uni.showToast({
                                                icon:"none",
                                                title:"验证码发送失败"
                                            })
                                        }
                                    },
                                    resetHandler:()=>{
                                        this.cli.close();
                                        this.getcode();
                                    }
                                });
                }).catch(error=>{console.log(error)});
            },