美文网首页
【uni-app】实现h5环境下页面弹出通知消息

【uni-app】实现h5环境下页面弹出通知消息

作者: 北极星丶超帅的 | 来源:发表于2020-03-13 10:02 被阅读0次

最近用uin-app的做项目,要弄推送通知的,由于H5不能控制通知栏,便退而求其次要在页面显示通知,虽然觉得有点鸡肋,但这是需求,只能埋头敲代码,以为是要每个页面都显示,所以自己画了一个页面,在全局挂载到body下,以下是效果图,配合使用【前端】node+express模拟websocket通信更加

效果GIF.gif

在文件夹下创建了这两个文件


image.png

notify-push-model.vue

<template>
    <!-- 通知栏 -->
    <view class="notify-push-model fadeIn" :class="[type, translate]" v-if="visible" @touchstart="start" @touchend="end">
        <view>{{ text }}</view>
        <view class="more-text" v-if="isShowMore">查看更多>></view>
        <view class="notify-push-model-close cross" @click.stop="onClose"></view>
    </view>
</template>

<script>
export default {
    props: {
        duration: {
            // 显示时间
            type: Number,
            default: 3000
        },
        transition: {
            // 是否开启动画
            type: Boolean,
            default: true
        }
    },
    data() {
        return {
            visible: false,
            type: '',
            text: '',
            translate: '',
            startData: {},
            closeDuration: 300,
            isShowMore: false
        };
    },
    computed: {
        isRing() {
            return this.$store.state.isRing; //是否铃声
        },
        isNotificationBar() {
            return this.$store.state.isNotificationBar; //是否通知
        },
        isShock() {
            return this.$store.state.isShock; //是否震动
        }
    },
    methods: {
        // 通知音效
        playAudio() {
            const innerAudioContext = uni.createInnerAudioContext();
            innerAudioContext.autoplay = true;
            innerAudioContext.src = '/static/audio/notify-2.mp3';
            innerAudioContext.onPlay(() => {
                // console.log('通知音效 - 播放');
            });
            innerAudioContext.onError(res => {
                console.log('通知音效 - 报错',res.errCode);
            });
        },

        // 设备震动
        onVibrate() {
            let vibrate = navigator.vibrate || navigator.webkitVibrate || navigator.mozVibrate || navigator.msVibrate;
            if (vibrate) {
                navigator.vibrate([500, 300, 400, 300]);
            } else {
                console.warn('不支持设备震动!');
            }
        },

        open() {
            //开启通知栏时
            if (this.isNotificationBar) {
                this.visible = true;
                if (this.isRing) {
                    setTimeout(() => {
                        this.playAudio();
                    }, 0);
                }
                if (this.isShock) {
                    this.onVibrate();
                }
            }
        },

        // 自动隐藏
        autoHide() {
            setTimeout(() => {
                this.translate = 'top-leave';
                this.close('noMore');
            }, this.duration - this.closeDuration);
        },

        // 隐藏消息通知
        close(type) {
            setTimeout(() => {
                this.translate = '';
                this.visible = false;
                this.isShowMore = type === 'noMore' ? false : true; //如果是自己关闭的就隐藏更多,如果是消息太多关闭之前的就显示更多
            }, this.closeDuration);
        },

        // 关闭按钮
        onClose() {
            this.translate = 'top-leave';
            this.close('noMore');
        },

        // 开始滑动
        start(e) {
            this.startData.clientX = e.changedTouches[0].clientX;
            this.startData.clientY = e.changedTouches[0].clientY;
        },

        // 滑动结束
        end(e) {
            const subX = e.changedTouches[0].clientX - this.startData.clientX;
            const subY = e.changedTouches[0].clientY - this.startData.clientY;
            if (subY > 50 || subY < -50) {
                this.translate = '';
                console.log('上下滑');
            } else {
                if (subX > 100) {
                    //右滑
                    this.translate = 'right-leave';
                    this.close('noMore');
                } else if (subX < -100) {
                    //左滑
                    this.translate = 'left-leave';
                    this.close('noMore');
                } else {
                    this.translate = '';
                    console.log('滑动无效');
                }
            }
        }
    }
};
</script>
<style lang="scss" scoped>
/*弹层动画(从上往下)*/
.fadeIn {
    -webkit-animation: fadeInDown 0.5s;
    animation: fadeInDown 0.5s;
}

@keyframes fadeInDown {
    0% {
        transform: translate3d(0, -100%, 0);
        opacity: 0;
    }
    100% {
        -webkit-transform: none;
        transform: none;
        opacity: 1;
    }
}

.top-leave {
    transform: translateY(-110%);
    transition-timing-function: cubic-bezier(0.36, 0.66, 0.04, 1);
}
.right-leave {
    transform: translateX(110%);
    transition-timing-function: cubic-bezier(0.36, 0.66, 0.04, 1);
}
.left-leave {
    transform: translateX(-110%);
    transition-timing-function: cubic-bezier(0.36, 0.66, 0.04, 1);
}

// 消息通知框
.notify-push-model {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 2000;
    width: 100%;
    height: auto;
    min-height: 50rpx;
    font-size: 30rpx;
    font-family: PingFang-SC-Medium;
    color: #f1f1f1;
    background: rgba($color: #000000, $alpha: 0.8);
    border-radius: 10rpx;
    padding: 25rpx 70rpx 25rpx 30rpx;
    box-sizing: border-box;
    transition-property: width, height, transform, background, font-size;
    transition-duration: 0.3s, 0.3s, 0.3s, 0.3s, 0.3s;
    box-shadow: 0 2rpx 12rpx 0 rgba($color: #000000, $alpha: 0.1);
    // transform: translateY(-100%);
    opacity: 0.9;
}

// 关闭按钮
.notify-push-model-close {
    position: absolute;
    top: 50%;
    right: 0;
    width: 30rpx;
    height: 30rpx;
    padding: 20rpx 20rpx;
    &::before,
    &::after {
        content: '';
        position: absolute;
        display: flex;
        justify-content: center;
        background: #f1f1f1;
        top: 0;
        left: 19rpx;
        width: 30rpx;
        height: 3rpx;
    }
    &::before {
        transform: rotate(45deg);
    }
    &::after {
        transform: rotate(-45deg);
    }
}

// 主要
.notify-push-model.primary {
    color: #f1f1f1;
    background: rgba($color: #0f88eb, $alpha: 1);
    .cross {
        &::before,
        &::after {
            background: #f1f1f1;
        }
    }
}

// 成功
.notify-push-model.success {
    color: #f1f1f1;
    background: rgba($color: #07c160, $alpha: 1);
    .cross {
        &::before,
        &::after {
            background: #f1f1f1;
        }
    }
}

// 警告
.notify-push-model.warning {
    color: #bb9f4c;
    background: rgba($color: #fff0d6, $alpha: 1);
    .cross {
        &::before,
        &::after {
            background: #bb9f4c;
        }
    }
}

// 危险
.notify-push-model.danger {
    color: #f1f1f1;
    background: rgba($color: #f56c6c, $alpha: 1);
    .cross {
        &::before,
        &::after {
            background: #f1f1f1;
        }
    }
}

// 信息
.notify-push-model.info {
    color: #f1f1f1;
    background: rgba($color: #909399, $alpha: 1);
    .cross {
        &::before,
        &::after {
            background: #f1f1f1;
        }
    }
}

.more-text {
    font-size: 24rpx;
    text-align: right;
}
</style>

index.js

import notifyModel from '@/components/notify/notify-push-model'

const notify = {}
notify.install = (vue, options) => {
    const ToastCon = vue.extend(notifyModel)
    const ins = new ToastCon()
    ins.$mount(document.createElement('div'))
    document.body.appendChild(ins.$el)
    vue.prototype.$notify = {
        show(options) {
            if (ins.visible === true) { //如果已经是显示的
                ins.translate = 'top-leave';
                ins.close()
                setTimeout(() => {
                    if (typeof options === 'string') { // 对参数进行判断
                        ins.text = options
                    } else if (typeof options === 'object') {
                        Object.assign(ins, options) // 合并参数与实例
                    }
                    // ins.visible = true
                    ins.open()
                }, ins.closeDuration)

                if (typeof options === 'object' && options.auto) { //3s后自动隐藏
                    ins.autoHide()
                }
            } else {
                if (typeof options === 'string') { // 对参数进行判断
                    ins.text = options
                } else if (typeof options === 'object') {
                    Object.assign(ins, options) // 合并参数与实例
                }
                // ins.visible = true
                ins.open()
            }

        },
        hide() {
            ins.visible = false
            ins.translate = 'top-leave';
            ins.close()
        }

    }
}

export default notify;

main.js


/*==================|-- * 消息推送 * start --|==================*/
// #ifdef H5
import notify from '@/components/notify/index'
Vue.use(notify)
// #endif
/*==================|-- * 消息推送 * end--|==================*/
使用方法
this.$notify.show({ type: 'success', text: '您有新的订单,请注意查收!' });
//or
this.$notify.show('您有新的订单,请注意查收!' );

想模拟下在websocket通信下的状态,请点击这个页面配合使用【前端】node+express模拟websocket通信

相关文章

网友评论

      本文标题:【uni-app】实现h5环境下页面弹出通知消息

      本文链接:https://www.haomeiwen.com/subject/rrefshtx.html