Uni app full end custom modal box component uapopup (upgraded version)

Time:2021-11-14

Uni app full end custom modal box component uapopup (upgraded version)

uaPopupCompatible multi terminal based on uniappH5 + applet + app sideCustom bullet frame components.

Quick introduction

Global import in main.js.

import UAPopup from './components/ua-popup/index.vue'
Vue.component('ua-popup', UAPopup)

You can also use the easycom mode to import, so you need to change the structure tocomponents/ua-popup/ua-popup.vue

The following figure: perfect operation at multiple ends.
Uni app full end custom modal box component uapopup (upgraded version)

Uni app full end custom modal box component uapopup (upgraded version)

UA popup pop-up component supportTag + functionThere are two calling methods.

<!--  MSG prompt -- >
< UA pop V-model = "showmsg" anim = "fadein" content = "goodness is like water, water works for all things without contention" shadeclose = "false" time = "3" / >

<!--  Message box -- >
<ua-popup v-model="showInfo" anim="scaleIn"
    Content = "people can't walk out of their own shadow in the sun, and people can't see their own shadow in the dark. As long as there is tomorrow, today will always be the starting line."
    :btns="[
        {text: 'got it', style: 'color: #999;', click: hideinfo},
    ]"
/>
  • Functional formula
//Functional nested call
handleInfo() {
    let $ua = this.$refs.uapopup
    let $toast = this.$refs.uatoast
    $ua.open({
        Content: 'life is long, and you should cherish it',
        customStyle: {'background-color': 'rgba(170, 0, 127, 0.6)', 'color': '#fff'},
        time: 3,
        onClose() {
            $ua.open({
                type: 'android',
                Content: '< div style = "color: #aa007f" > the best way to predict the future is to create the future by yourself < / div >',
                customStyle: {'width': '200px'},
                zIndex: 202120,
                btns: [
                    {
                        text: 'close', click() {
                            $ua.close()
                        }
                    },
                    {
                        Text: 'get once',
                        style: 'color:#00aa00;',
                        click() {
                            $toast.open({
                                type: 'toast',
                                icon: 'loading',
                                Content: 'please wait...',
                                opacity: .2,
                                time: 2,
                                zIndex: 202125,
                            })
                        }
                    }
                ]
            })
        }
    })
},
handleBtnClick() {
    this.$refs.uapopup.open({
        Content: 'operation in progress, please wait...',
        shadeClose: false,
        anim: 'footer',
        customStyle: {'background-color': 'rgba(0, 170, 0, 0.6)', 'color': '#fff', 'border-radius': '6px'},
        opacity: .1,
        time: 2,
        onClose: () => {
            this.$refs.uatoast.open({
                Type: 'toast', Icon: 'success', content:' operation succeeded ', time: 2,
            })
        }
    });
},

Implementation process

  • Support 20 + parameter configuration
    Whether the current component of V-model is displayed
    Title Title (support rich text div label and custom slot content)
    Content (supports rich text div tags and custom slot content)
    Type pop up window type (toast | footer | actionsheet | actionsheetpicker | Android / IOS)
    Customstyle custom pop-up style
    Icon toast icon (loading | success | fail | warn | info)
    Does the shade display mask layers
    Shadeclose whether to close the pop-up window when the mask is clicked
    Opacity mask layer transparency
    Does round show rounded corners
    Whether xclose displays the close icon
    Xposition close icon position (left | right | top | bottom)
    Xcolor turn off icon color
    Anim pop up animation (scalein | fadein | footer | fadeinup | fadeindown)
    Position pop-up position (top | right | bottom | left)
    Follow long press / right click to pop up the window (coordinate point)
    Time pop-up window automatically closes seconds (1, 2, 3)
    Zindex pop-up window cascade (default 202107)
    BTNs pop up button (parameter: text style disabled click)
    Triggered when the pop-up layer is opened (@ open = "XXX")
    Close triggered when the pop-up layer is closed (@ close = "XXX")
    Onopen pop up callback
    Onclose close popup callback
<template>
    <!-- #ifdef APP-NVUE -->
    <view v-if="opts.visible" class="ua__popup" :class="{'ua__popup-closed': closeAnim}">
    <!-- #endif -->
    <!-- #ifndef APP-NVUE -->
    <view v-show="opts.visible" class="ua__popup" :class="{'ua__popup-closed': closeAnim}">
    <!-- #endif -->
        <!--  Mask layer -- >
        <view v-if="opts.shade && opts.shade!='false'" class="uapopup__overlay" @touchstart="handleShadeClick" :style="{'opacity': opts.opacity >= 0 ? opts.opacity : '', 'z-index': oIndex-1}"></view>
        <!--  Window layer -- >
        <view class="uapopup__wrap" :style="{'z-index': oIndex}">
            <view class="uapopup__child" :id="'uapopup-'+uuid" :class="['anim-'+opts.anim, opts.type&&'popui__'+opts.type, opts.round&&'round', opts.position]" :style="[opts.follow&&positionStyle, opts.customStyle]">
                <!-- // Title -- >
                <view v-if="opts.title || $slots.title" class="uapopup__title">
                    <template v-if="$slots.title"><slot name="title" /></template>
                    <rich-text v-else :nodes="opts.title"></rich-text>
                </view>

                <!-- //toast -->
                <!-- <view v-if="opts.type=='toast'&&opts.icon" class="toast__icons" :class="['toast__icons-'+opts.icon]" :style="{'background-image': `url(${toastIcon[opts.icon]})`}"></view> -->
                <image v-if="opts.type=='toast'&&opts.icon" class="toast__icons" :class="['toast__icons-'+opts.icon]" :src="toastIcon[opts.icon]" mode="widthFix"></image>
                <!-- // Content -- >
                <view v-if="opts.content || $slots.content" class="uapopup__content">
                    <template v-if="$slots.content"><slot name="content" /></template>
                    <rich-text v-else :nodes="opts.content"></rich-text>
                </view>
                <slot />

                <!-- // Button group -- >
                <view v-if="opts.btns" class="uapopup__actions">
                    <rich-text v-for="(btn,index) in opts.btns" :key="index" class="btn" :class="{'disabled': btn.disabled}" :style="btn.style" @click="handleBtnClick($event, index)" :nodes="btn.text"></rich-text>
                </view>

                <!-- // Close button -- >
                <view v-if="opts.xclose" class="uapopup__xclose" :class="opts.xposition" :style="{'color': opts.xcolor}" @click="close"></view>
            </view>
        </view>
    </view>
</template>

<script>
/**
 *@ desc uniapp full end custom pop-up components
 * @Time     andy by 2021/7/10
 * @About    Q:282310962  wx:xy190310
 */
    let index = 0
    export default {
        ...
        data() {
            return {
                //Mix props parameters to handle functional calls
                opts: {
                    visible: false,
                },
                toastIcon: {
                    ...
                },
                closeAnim: false,
                oIndex: 202107,
                timer: null,
                //Long press positioning initialization (avoid bounce and flicker of pop-up frame)
                positionStyle: { position: 'absolute', left: '-999px', top: '-999px' },
            }
        },
        watch: {
            value(val) {
                const type = val ? 'open' : 'close'
                this[type]()
            }
        },
        computed: {
            uuid() {
                return Math.floor(Math.random() * 10000)
            },
        },
        methods: {
            //Open the pop-up box
            open(options) {
                if(this.opts.visible) return
                this.opts = Object.assign({}, this.$props, options)
                this.opts.visible = true

                //The components of nvue are transparent by default at the Android end. If background color is not set, ghosting may occur
                // #ifdef APP-NVUE
                if(!this.opts.customStyle['background'] && !this.opts.customStyle['background-color']) {
                    this.opts.customStyle['background'] = '#fff'
                }
                // #endif

                let _index = ++index
                this.oIndex = _index + parseInt(this.opts.zIndex)

                this.$emit('open')
                typeof this.opts.onOpen === 'function' && this.opts.onOpen()

                //Long press processing
                if(this.opts.follow) {
                    ...
                }

                ...
            },
            //Close the bullet box
            close() {
                if(!this.opts.visible) return

                this.closeAnim = true
                setTimeout(() => {
                    this.opts.visible = false
                    this.closeAnim = false

                    this.$emit('input', false)
                    this.$emit('close')
                    typeof this.opts.onClose === 'function' && this.opts.onClose()

                    this.timer && clearTimeout(this.timer)
                    delete this.timer
                }, 200)
            },

            ...

            //Get DOM width and height
            getDom(id) {
                return new Promise((resolve, inject) => {
                    uni.createSelectorQuery().in(this).select('#uapopup-' + id).fields({
                        size: true,
                    }, data => {
                        resolve(data)
                    }).exec()
                })
            },

            //Adaptive coordinate point
            getPos(x, y, ow, oh, winW, winH) {
                let l = (x + ow) > winW ? x - ow : x;
                let t = (y + oh) > winH ? y - oh : y;
                return [l, t];
            },
        }
    }
</script>

Well, the above is the sharing of user-defined pop-up windows for uniapp development. Hope to help you!

Electron11 imitates QQ + wechat desktop chat | vue3. X + antdv + electron cross end chat application

Electron13 + vue3 hybrid desktop exe application framework electronmacui

Uni app full end custom modal box component uapopup (upgraded version)

This work adoptsCC agreement, reprint must indicate the author and the link to this article

This article is an original article and cannot be reproduced without the permission of the author. You are welcome to exchange QQ (282310962) Wx (xy190310)