广告位联系
返回顶部
分享到

自己写一个uniapp全局弹窗(APP端)

JavaScript 来源:互联网 作者:佚名 发布时间:2022-10-20 21:52:15 人浏览
摘要

效果图: uniapp自带的提示框不符合我们的要求,需要自己写一个提示框,且全局通用。 解决思路: 使用 plus.nativeObj 来绘制窗口以及事件监听。 官方文档 方法如下: 1. 首先创建一个整

效果图: 

 uniapp自带的提示框不符合我们的要求,需要自己写一个提示框,且全局通用。

解决思路:

使用 plus.nativeObj 来绘制窗口以及事件监听。    官方文档

方法如下:

1. 首先创建一个整个屏幕的控件,作为一个父容器。

此时还看不到任何东西

1

2

3

4

5

6

7

8

9

10

11

12

let screenHeight = uni.getSystemInfoSync().screenHeight;

let style = {

    width:'100%',

    height: (screenHeight + 'px'),

    left:'0px',

    top:'0px'

};

  

// 创建原生控件对象

// 参数1: id

// 参数2: 控件的样式

let view = new plus.nativeObj.View('showModalView',style);

2. 绘制遮罩层

1

2

3

4

5

6

7

8

9

10

11

view.draw([

    {tag:'rect',id:'modal',color:`rgba(0,0,0,0.4)`,position:{top:'0px',left:'0px',width:'100%',height:'100%'}}

]);

  

  

{

    tag:'rect',                        // 绘制矩形

    id:'modal',                        // 控件id

    color:`rgba(0,0,0,0.4)`,            // 背景色

    position:{top:'0px',left:'0px',width:'100%',height:'100%'}        // 位置和大小样式

}

view.draw(tags); 在控件上绘制,传入绘制对象。

绘制对象文档 可绘制图片、矩形区域、文本等内容。  

3.绘制通知框样式

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

view.draw([

    {tag:'rect',id:'modal',color:`rgba(0,0,0,0.4)`,position:{top:'0px',left:'0px',width:'100%',height:'100%'}},

    {tag:'rect',id:'content',rectStyles:{borderWidth:'2px',radius:'8px',color:`rgba(36,34,56,1)`},position:{top:startTop+'px',left:startLeft+'px',width:width+'px',height:height+'px'}},

]);

  

{

    tag:'rect',

    id:'content',

    // 矩形的样式

    rectStyles:{borderWidth:'2px',radius:'8px',color:`rgba(36,34,56,1)`},

    // 位置和大小. 下面的变量是根据屏幕宽高手动计算的

    position:{top:startTop+'px',left:startLeft+'px',width:width+'px',height:height+'px'}

}

  

interface RectStyles {

    attribute String color;

    attribute String radius;

    attribute String borderColor;

    attribute String borderWidth;

}  

4. 绘制标题和内容

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

view.draw([

    {tag:'rect',id:'modal',color:`rgba(0,0,0,0.4)`,position:{top:'0px',left:'0px',width:'100%',height:'100%'}},

    {tag:'rect',id:'content',rectStyles:{borderWidth:'2px',radius:'8px',color:`rgba(36,34,56,1)`},position:{top:startTop+'px',left:startLeft+'px',width:width+'px',height:height+'px'}},

    {tag:'font',id:'title',text:modelInfo.tit,textStyles:{size:'16px',color:'#fff'},position:{top:titleTop+'px',left:startLeft+'px',width:width+'px',height:titleHeight+'px'}},

    {tag:'font',id:'text',text:modelInfo.content,textStyles:{size:'14px',color:'#fff',whiteSpace:'normal',align:modelInfo.align},position:{top:contentTop+'px',left:startLeft+'px',width:width+'px',height:contentHeight+'px'}},

    // 这个是内容和底部按钮的分割线

    {tag:'rect',id:'line',color:'rgba(255,255,255,0.3)',position:{top:lineTop+'px',left:startLeft+'px',width:width+'px',height:'0.5px'}},

]);

  

{

    tag:'font',                    // 绘制文字

    id:'title',

    text:modelInfo.tit,            // 文字内容

    textStyles:{size:'16px',color:'#fff'},

    position:{top:titleTop+'px',left:startLeft+'px',width:width+'px',height:titleHeight+'px'}

},

5. 创建确认按钮控件

我们需要给确认按钮设置点击事件,所以它要作为一个新的控件,而不是再刚刚的控件上继续绘制。

1

2

3

4

5

6

7

8

9

10

11

12

13

// 确认

let viewconfirm=new plus.nativeObj.View('confirm',

    {

        width:modelInfo.delCancel?width+'px':'40%',

        height:buttonHeight+'px',

        top:lineTop+'px',

        left:modelInfo.delCancel?startLeft+'px':halfWidthForGlobal +'px',

        backgroundColor:'rgba(255,255,255,0)',

    },

);

viewconfirm.draw([

    {tag:'font',id:'confirm',text:modelInfo.confirmVal,textStyles:{color:modelInfo.confirmColor,size:'14px'}},

]);

设置点击事件

1

2

3

4

5

6

viewconfirm.addEventListener("click",(e)=>{

    // 发送事件

    this.$event({res:true,types:'confirm'});

    // 隐藏当前控件(关闭)

    this.hide();

},false);

将 viewconfirm和view显示出来:

1

2

3

4

function show(){

    this.view.show();

    this.confirmModel.show();

}

下面就是将这些挂载到Uni上就可以了。

下面是项目中的完整代码:

index.js 用于绘制

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

// show_modal/index.js

export class show_model{

    constructor(option={}) {

        this.bodyModel=null;

        this.cancelModel=null;

        this.confirmModel=null;

        this.pageHeight=uni.getSystemInfoSync().screenHeight;

        this.pageWidth = uni.getSystemInfoSync().screenWidth;

        let opacity = option.opacity || 0.4;

        let model_tit=option.title||'温馨提示';

        let model_content=option.content||"内容"

        let clickEvent=option.IsclickEvent||false;

        let cancelVal=option.cancelVal||'取消';

        let confirmVal=option.confirmVal||'确认';

        let cancelColor=option.cancelColor||'#fff';             // 取消

        let confirmColor=option.confirmColor||'#fff';           // 确认

        let delCancel=option.delCancel||false;

        let align=option.align||"center";

        let fn = ()=>{};

        this.$event = option.$event || fn;

        let backOff=option.backOff||false;

         

        //#ifdef APP-PLUS

        this.creatView({height:`${this.pageHeight}px`,top:0},opacity,clickEvent,{'tit':model_tit,'content':model_content,cancelVal,confirmVal,confirmColor,cancelColor,delCancel,align})

        if(!backOff){

            this.backbtn();

        }

        //#endif

    }

    backbtn(){

        let that=this;

        plus.key.addEventListener('backbutton', function (e) {

            that.hide();

        },false)

    }

    //生成提示框view

    creatView(style,opa,clickEvent,modelInfo){

        style = {

            left:'0px',

            width:'100%',

            ...style

        }

        let platform = plus.os.name.toLowerCase();

        let view = new plus.nativeObj.View('showModalView',style);

         

        let width = 300;

        let height = 150;

        let titleHeight = 20;

        let contentHeight = 60;

        let startTop = (this.pageHeight - height) / 2;

        let startLeft = (this.pageWidth - width) / 2;

        let titleTop = startTop + 10;

        let contentTop = titleTop+30;

        let lineTop = startTop + height - 40;

        let buttonHeight = 40;

        let halfWidth = width / 2;

        let halfWidthForGlobal = startLeft + halfWidth;

         

        if(platform == "ios"){

            view.draw([

                {tag:'rect',id:'modal',color:`rgba(0,0,0,${opa})`,position:{top:'0px',left:'0px',width:'100%',height:'100%'}},

                {tag:'rect',id:'content',rectStyles:{borderWidth:'2px',radius:'8px',color:`rgba(36,34,56,1)`},position:{top:startTop+'px',left:startLeft+'px',width:width+'px',height:height+'px'}},

                {tag:'font',id:'title',text:modelInfo.tit,textStyles:{size:'16px',color:'#fff'},position:{top:titleTop+'px',left:startLeft+'px',width:width+'px',height:titleHeight+'px'}},

                {tag:'font',id:'text',text:modelInfo.content,textStyles:{size:'14px',color:'#fff',whiteSpace:'normal',align:modelInfo.align},position:{top:contentTop+'px',left:startLeft+'px',width:width+'px',height:contentHeight+'px'}},

                {tag:'rect',id:'line',color:'rgba(255,255,255,0.3)',position:{top:lineTop+'px',left:startLeft+'px',width:width+'px',height:'0.5px'}},

                {tag:'rect',id:'line2',color:'rgba(255,255,255,0.3)',position:{top:lineTop+'px',left:+halfWidthForGlobal+'px',width:modelInfo.delCancel?'0px':'0.5px',height:modelInfo.delCancel?'0px':buttonHeight+'px'}}

            ]);

        }else{

            view.draw([

                {tag:'rect',id:'modal',color:`rgba(0,0,0,${opa})`,position:{top:'0px',left:'0px',width:'100%',height:'100%'}},

                {tag:'rect',id:'content',rectStyles:{borderWidth:'2px',radius:'8px',color:`rgba(36,34,56,1)`},position:{top:startTop+'px',left:startLeft+'px',width:width+'px',height:height+'px'}},

                {tag:'font',id:'title',text:modelInfo.tit,textStyles:{size:'16px',color:'#fff'},position:{top:titleTop+'px',left:startLeft+'px',width:width+'px',height:titleHeight+'px'}},

                {tag:'font',id:'text',text:modelInfo.content,textStyles:{size:'14px',color:'#fff',whiteSpace:'normal',align:modelInfo.align},position:{top:contentTop+'px',left:startLeft+'px',width:width+'px',height:contentHeight+'px'}},

                {tag:'rect',id:'line',color:'rgba(255,255,255,0.3)',position:{top:lineTop+'px',left:startLeft+'px',width:width+'px',height:'0.5px'}},

                {tag:'rect',id:'line2',color:'rgba(255,255,255,0.3)',position:{top:lineTop+'px',left:halfWidthForGlobal+'px',width:modelInfo.delCancel?'0px':'0.5px',height:modelInfo.delCancel?'0px':buttonHeight+'px'}}

            ]);

        }

         

        var num = 0.55;

        if(platform == "ios"){

            num = 0.57

        }

        if(!modelInfo.delCancel){

            // 取消  

            let viewCancel=new plus.nativeObj.View('cancel',{width:halfWidth+'px',height:buttonHeight+'px',top:lineTop+'px',left:startLeft+'px',backgroundColor:'rgba(255,255,255,0)'});

                viewCancel.draw([

                  {tag:'font',id:'cancel',text:modelInfo.cancelVal,textStyles:{color:modelInfo.cancelColor,size:'14px'}},

                ]);

                 

                viewCancel.addEventListener("click",(e)=>{

                    this.$event({res:false,types:'cancel'});

                    this.hide();

                },false);

                this.cancelModel=viewCancel;

        }

        // 确认

        let viewconfirm=new plus.nativeObj.View('confirm',

            {

                width:modelInfo.delCancel?width+'px':'40%',

                height:buttonHeight+'px',

                top:lineTop+'px',

                left:modelInfo.delCancel?startLeft+'px':halfWidthForGlobal +'px',

                backgroundColor:'rgba(255,255,255,0)',

            },

        );

        viewconfirm.draw([

            {tag:'font',id:'confirm',text:modelInfo.confirmVal,textStyles:{color:modelInfo.confirmColor,size:'14px'}},

        ]);

     

        viewconfirm.addEventListener("click",(e)=>{

            this.$event({res:true,types:'confirm'});

            this.hide();

        },false);

          //点击蒙布

        if(clickEvent){

             view.addEventListener("click", (e) => {

                this.$event({res:false,types:'cover'});

                this.hide();

            }, false);

        }

       this.bodyModel=view;

       this.confirmModel=viewconfirm;

    }

    showModalAnimationClose(){

        var options = {type:'pop-out',duration:300};

            plus.nativeObj.View.startAnimation(options,{view:this.bodyModel},{view:this.cancelModel},{view:this.viewconfirm},function(){

                console.log('plus.nativeObj.View.startAnimation动画结束');

                // 关闭原生动画

                plus.nativeObj.View.clearAnimation();

            });

    }

    showModalAnimationOpen(){

        var options = {type:'pop-in',duration:1000};

         

            plus.nativeObj.View.startAnimation(options,{view:this.bodyModel},{view:this.cancelModel},{view:this.viewconfirm},function(){

                console.log('plus.nativeObj.View.startAnimation动画结束');

                // 关闭原生动画

                plus.nativeObj.View.clearAnimation();

            });

    }

    show(){

        this.showModalAnimationOpen();

        this.bodyModel.show();

        if(this.cancelModel){

            this.cancelModel.show();

        }

        this.confirmModel.show();

     

    }

    hide(){

        this.showModalAnimationClose();

        this.bodyModel.hide();

        if(this.cancelModel){

          this.cancelModel.hide(); 

        }

        this.confirmModel.hide();

    }

}

  

export default show_model

show_modal.js: 用于创建promise对象并挂载

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

// show_modal/xt_show_modal.js

import show_modal from './index.js'

  

const xt_show_modal = {

    install: function(Vue) {

        const show_modal_fun=function(op={}){

            //#ifdef APP-PLUS

            return  new Promise((resolve, reject)=>{

               let ssm=new show_modal({

                    ...op,

                    $event:function(e){

                        if(e.res){

                            resolve(e);

                        }else{

                            reject(e);

                        }

                     }

                });

                ssm.show();

                Vue.prototype.$hide=function(){

                    ssm.hide();

                }

            })

            //#endif

             

            // 适应H5

            //#ifdef H5

                var promise=uni.showModal({

                    title: op.title,

                    content: op.content,

                    showCancel: !op.delCancel,

                    cancelText: op.cancelVal,

                    confirmText: op.confirmVal,

                });

                 

                return new Promise((resolve,reject)=>{

                    promise.then(data=>{

                        var [err, res] = data;

                        if(res.confirm){

                            resolve()

                        }else{

                            reject();

                        }

                    })

                })

                 

            //#endif

             

        }

        // $showModal挂载到uni对象上

        uni.$showModal = show_modal_fun

        Vue.prototype.$showModal = show_modal_fun

    }

};

  

export default xt_show_modal;

main.js中挂载

1

2

3

// 自定义showModal组件

import xt_show_modal from '@/component/show_modal/xt_show_modal.js'

Vue.use(xt_show_modal);

使用:

1

2

3

4

5

6

7

8

9

10

11

12

// showModel的使用

uni.$showModal({

    title:"",               //可选,不填则不显示

    content:'未知错误,请联系管理员!',

    delCancel: true,

    confirmVal: '知道了',  // 可选

    cancelVal:'取消',     // 可选

}).then(res=>{

    // 点击确认按钮点击事件

}).catch(res=>{

    // 点击取消按钮点击事件

});


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 : https://blog.csdn.net/qq_18594435/article/details/126073115
相关文章
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计